developer tip

BottomNavigationView 레이블 제거

copycodes 2021. 1. 9. 10:12
반응형

BottomNavigationView 레이블 제거


Google은 BottomNavigationView와 함께 새로운 지원 라이브러리 v25를 출시했습니다.

여기에 이미지 설명 입력

항목 레이블을 제거하는 방법이 있습니까?


여기 파티에 너무 늦지 않았 으면 좋겠어요.

그러나 Design Support Library 28.0.0-alpha1부터는 속성을 사용할 수 있습니다.

app:labelVisibilityMode="unlabeled"

레이블이없는 BottomNavigationView

다른 값 "auto", "labeled"및 "selected"도 사용할 수 있습니다.


이 스타일을 원하십니까?

그렇다면 BottomNavigationViewEx 를 사용해 보는 것이 좋습니다 .


불행히도이 첫 번째 BottomNavigationView 버전에는 많은 제한이있었습니다. 그리고 지금은 지원 디자인 API를 사용하여 제목을 제거 할 수 없습니다. 따라서 Google이 구현하지 않는 동안이 제한을 해결하려면 다음을 수행하십시오 (반사 사용).

1. bottom_navigation_menu.xml 파일에서 제목을 비워 둡니다.

2. BottomNavigationView를 확장합니다.

    public class MyBottomNavigationView extends BottomNavigationView {

      public MyBottomNavigationView(Context context, AttributeSet attrs) {
          super(context, attrs);
          centerMenuIcon();
      }

      private void centerMenuIcon() {
          BottomNavigationMenuView menuView = getBottomMenuView();

          if (menuView != null) {
              for (int i = 0; i < menuView.getChildCount(); i++) {
                BottomNavigationItemView menuItemView = (BottomNavigationItemView) menuView.getChildAt(i);

                AppCompatImageView icon = (AppCompatImageView) menuItemView.getChildAt(0);

                FrameLayout.LayoutParams params = (LayoutParams) icon.getLayoutParams();
                params.gravity = Gravity.CENTER;

                menuItemView.setShiftingMode(true);
              }
          }
      }

      private BottomNavigationMenuView getBottomMenuView() {
          Object menuView = null;
          try {
              Field field = BottomNavigationView.class.getDeclaredField("mMenuView");
              field.setAccessible(true);
              menuView = field.get(this);
          } catch (NoSuchFieldException | IllegalAccessException e) {
              e.printStackTrace();
          }

          return (BottomNavigationMenuView) menuView;
      }
    }

3.이 customView를 layout.xml에 추가하십시오.

자세한 내용은 Github에서 구현했습니다.


1. menu / abc.xmlandroid:title=""; 에서 설정

2. 리플렉션을 사용하는 아래 도우미 클래스를 만듭니다.

import android.support.design.internal.BottomNavigationMenuView;
import android.support.design.widget.BottomNavigationView;
import android.support.v7.widget.AppCompatImageView;
import android.util.Log;
import android.view.Gravity;
import android.widget.FrameLayout;

import java.lang.reflect.Field;

public class BottomNavigationViewHelper {
    public static void disableShiftMode(BottomNavigationView view) {
        BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
        try {
            Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
            shiftingMode.setAccessible(true);
            shiftingMode.setBoolean(menuView, false);
            shiftingMode.setAccessible(false);
            for (int i = 0; i < menuView.getChildCount(); i++) {
                BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
                //noinspection RestrictedApi
                item.setShiftingMode(false);
                item.setPadding(0, 15, 0, 0);
                // set once again checked value, so view will be updated
                //noinspection RestrictedApi
                item.setChecked(item.getItemData().isChecked());
            }
        } catch (NoSuchFieldException e) {
            Log.e("BNVHelper", "Unable to get shift mode field", e);
        } catch (IllegalAccessException e) {
            Log.e("BNVHelper", "Unable to change value of shift mode", e);
        }
    }
} 

3. 기본 활동에서 다음 행을 추가하십시오.

mBottomNav = (BottomNavigationView) findViewById(R.id.navigation);
BottomNavigationViewHelper.disableShiftMode(mBottomNav);

무반사 접근 :

private void removeTextLabel(@NonNull BottomNavigationView bottomNavigationView, @IdRes int menuItemId) {
    View view = bottomNavigationView.findViewById(menuItemId);
    if (view == null) return;
    if (view instanceof MenuView.ItemView) {
        ViewGroup viewGroup = (ViewGroup) view;
        int padding = 0;
        for (int i = 0; i < viewGroup.getChildCount(); i++) {
            View v = viewGroup.getChildAt(i);
            if (v instanceof ViewGroup) {
                padding = v.getHeight();
                viewGroup.removeViewAt(i);
            }
        }
        viewGroup.setPadding(view.getPaddingLeft(), (viewGroup.getPaddingTop() + padding) / 2, view.getPaddingRight(), view.getPaddingBottom());
    }
}

이것은 일시적인 수정입니다. 추가하면됩니다. app:itemTextColor="@android:color/transparent"배경색이 무엇이든지간에 비활성화 된 것처럼 보입니다. 아이콘이 상승 된 것처럼 보입니다.


시프트 애니메이션 과 레이블을 모두 제거하고 싶었지만 여기에서 잘 작동하지 않는 솔루션이 없으므로 여기에서 배운 모든 것을 기반으로 구축 한 솔루션이 있습니다.

public void removeLabels(@IdRes int... menuItemIds) {
    getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        @Override public boolean onPreDraw() {
            getViewTreeObserver().removeOnPreDrawListener(this);

            // this only needs to be calculated once for an unchecked item, it'll be the same value for all items
            ViewGroup uncheckedItem = findFirstUncheckedItem(menuItemIds);
            View icon = uncheckedItem.getChildAt(0);
            int iconTopMargin = ((LayoutParams) uncheckedItem.getChildAt(0).getLayoutParams()).topMargin;
            int desiredTopMargin = (uncheckedItem.getHeight() - uncheckedItem.getChildAt(0).getHeight()) / 2;
            int itemTopPadding = desiredTopMargin - iconTopMargin;

            for (int id : menuItemIds) {
                ViewGroup item = findViewById(id);
                // remove the label
                item.removeViewAt(1);
                // and then center the icon
                item.setPadding(item.getPaddingLeft(), itemTopPadding, item.getPaddingRight(),
                        item.getPaddingBottom());
            }

            return true;
        }
    });
}

@SuppressLint("RestrictedApi")
private ViewGroup findFirstUncheckedItem(@IdRes int... menuItemIds) {
    BottomNavigationItemView item = findViewById(menuItemIds[0]);
    int i = 1;
    while (item.getItemData().isChecked()) {
        item = findViewById(menuItemIds[i++]);
    }
    return item;
}

이 메소드를 사용자 정의에 추가 BottomNavigationView하고 메뉴 항목의 ID를 전달하여 호출하십시오.


sanf0rd가 그의 답변에서 준 것처럼 직접 구현하는 것이 좋습니다 . 그러나 AppCompatImageView나를 위해 일하지 않습니다. 나는 그것을 ImageView. 그리고 변화 getChildAtfindViewById.

또한 선택하지 않은 항목의 모든 레이블을 숨 깁니다.

private void centerMenuIcon() {
    BottomNavigationMenuView menuView = getBottomMenuView();
    if (menuView != null) {
        for (int i = 0; i < menuView.getChildCount(); i++) {
            BottomNavigationItemView menuItemView = (BottomNavigationItemView) menuView.getChildAt(i);
            TextView smallText = (TextView) menuItemView.findViewById(R.id.smallLabel);
            smallText.setVisibility(View.INVISIBLE);
            //TextView largeText = (TextView) menuItemView.findViewById(R.id.largeLabel);
            ImageView icon = (ImageView) menuItemView.findViewById(R.id.icon);
            FrameLayout.LayoutParams params = (LayoutParams) icon.getLayoutParams();
            params.gravity = Gravity.CENTER;
            menuItemView.setShiftingMode(true);
        }
    }
}

참조 URL : https://stackoverflow.com/questions/40183239/remove-bottomnavigationview-labels

반응형