본문 바로가기
Project/안드로이드 프로젝트(HomingBird)

Android Studio, JAVA] Material Design / Drawer Navigation에서, 기기에 따라 동적으로 메뉴를 가운데 두는 방법

by 김마리님 2020. 11. 9.

결과 : 

머티리얼 디자인 드로어 레이아웃은 디폴트가 메뉴가 위에 붙어있습니다. 이걸 아래에서 떼어내려하면 저~ 헤더뷰에서 marginBottom을 설정해주어야 합니다.

이걸 자바에서 어떻게 동적으로 처리해주냐~ 

코드 :

    private void initDrawerMenu(){
        //현재 네비게이션의 길이를 구함
        int navigationHeight = navigationView.getHeight();
        DlogUtil.d(TAG, navigationHeight);

        //전체 뷰 길이를 구함
        int height = drawerLayout.getHeight();
        DlogUtil.d(TAG, height);


        navigationView.setMinimumHeight(height);

        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) viewMenuHeader.getLayoutParams();
        layoutParams.bottomMargin = (height-navigationHeight)/2;

        viewMenuHeader.setLayoutParams(layoutParams);

    }

내비게이션의 길이, 그리고 화면을 채우는 전체 뷰의 길이를 구한 후 그냥 빼고 나누면 됩니다.

이 때, 내비게이션의 길이는 android:layout_height="wrap_content"이 되어야 올바르게 길이를 가져올 수 있습니다.

 

그리고 내비게이션 뷰에서 헤더의 뷰를 가져오는데, 이 함수는 

View viewMenuHeader = navigationView.getHeaderView(0);

입니다. 

 

그러나 이렇게 한다고 해서 적용이 되지는 않아요 ^-^ ... 뷰가 만들어지기 전에 이미 매서드가 작동되면서 0이 나와버리거든요 하하! 

그렇기 때문에 저는 Thread를 한번 더 적용했습니다.

(근데 스레드 방식보다 더 좋은 방식은 있을 것 같아요.)

 

그래서 아마 코드를 풀로 보면 이럴 것 같아요.

    private View viewMenuHeader;
    private NavigationView navigationView;
    
    private void findView(){
    
        navigationView = findViewById(R.id.navigation);
        viewMenuHeader = navigationView.getHeaderView(0);

       Thread thread = new Thread(() -> {
           try {
               Thread.sleep(100);
               runOnUiThread(() -> initDrawerMenu());
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       });

       thread.start();
    }
    
    private void initDrawerMenu(){
        //현재 네비게이션의 길이를 구함
        int navigationHeight = navigationView.getHeight();
        DlogUtil.d(TAG, navigationHeight);

        //전체 뷰 길이를 구함
        int height = drawerLayout.getHeight();
        DlogUtil.d(TAG, height);


        navigationView.setMinimumHeight(height);

        LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) viewMenuHeader.getLayoutParams();
        layoutParams.bottomMargin = (height-navigationHeight)/2;

        viewMenuHeader.setLayoutParams(layoutParams);

    }

 

이렇게 스레드를 지정하고, 0.1초라도 휴지기를 주어 뷰가 다 만들어지면 값을 가져올 수 있도록 합니다.

뷰는 무조건 UIThread가 만들기 때문에 반드시 runOnUIThread를 지정해주세요. (async task 방식은 제가 잘 사용하지 않아요.. 그냥 제가 그렇습니다.) 설정하지 않으면 view Touch on Hirec.. 오류가 뜨니까 보시고요. 오류를 읽읍시다.

 

(근데 전 이거 안쓸거에요 하하! 삽질하면서 만들고보니 별로라서!)

 

 

 

반응형