删除BottomNavigationView标签


82

Google发布了带有BottomNavigationView的新支持库v25

在此处输入图片说明

有什么办法可以删除物品标签?


1
您是否尝试title从菜单<item>s中删除s?
Mike M.

8
删除标题后,图标下方会有额外的填充。添加layout_marginBottom="-16dp"将删除此填充,但会使所有视图变小。
dzikovskyy

您可以代替设置边距,而是设置自定义高度,并在顶部添加一些额外的填充。这样,您可以将图标居中。
Bolling

4
我只是固定它是这样的:android:paddingTop="8dp" android:layout_marginBottom="-8dp" 这可以防止因小酒吧
棕榈

Answers:


198

我希望我来这里参加聚会不晚。

但是从Design Support Library 28.0.0-alpha1开始,您可以使用该属性

app:labelVisibilityMode="unlabeled"

没有标签的BottomNavigationView

您还可以使用其他值“ auto”,“ labeled”和“ selected”。


哪个支持库?v7还是设计?
Sagar Maiyad '18

设计支持库28.0.0
Abdul-Aziz-Niazi

最期待的功能。
bikram

1
您在哪个班级写作?
Explorex

1
@Explorex这是android的底部导航视图,我提到的属性是在所述视图的xml标记中使用的所述类的xml属性。您可以在代码中使用它太developer.android.com/reference/com/google/android/material/...
阿卜杜勒-阿齐兹-尼亚兹


18

不幸的是,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上实现了


无需使用反射,您可以BottomNavigationItemView通过调用findViewById()菜单项id来获取每个反射(就像@NikolaDespotoski在他的答案中所做的那样)。
FredPorciúncula18年

1
他们现在支持移除标签app:labelVisibilityMode="unlabeled"
Amjad Alwareh '19

13

1.android:title="";menu / abc.xml中设置

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);

11

无反射方式:

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());
    }
}

1
如果我要删除图标而不是文本
怎么办

我如何在已经存在默认BottomNavigation代码的主要活动中称呼它?@NikolaDespotoski
TiagoIB

@TiagoIB只是将方法设为静态并将其移至其他类。或者将其设为私有,并使用指定的参数调用它。
Nikola Despotoski

请问,如何将其插入代码中?prntscr.com/he03j7 @NikolaDespotoski
TiagoIB

6

这是一个临时修复。只需添加:app:itemTextColor="@android:color/transparent"无论背景颜色是什么,它都会显示为禁用状态。它的确使图标看起来升高了。


2

我想同时删除移位动画和标签,这里的解决方案都不适合我,因此这是我根据在这里学到的所有知识构建的解决方案:

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即可。


1

我建议按照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);
        }
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.