移除 BottomNavigationView 标签
Remove BottomNavigationView labels
Google 发布了带有 BottomNavigationView 的新支持库 v25
有什么方法可以删除项目标签吗?
不幸的是,第一个版本的 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。添加到layout.xml这个customView
有关详细信息,我已在 Github
上实现了此功能
无反射方法:
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"
这将使它无论背景颜色是什么,都显示为禁用。它确实使图标看起来更高。
你想要这种风格吗?
如果是这样,我建议您尝试 BottomNavigationViewEx。
我建议您自己实现 。但是 AppCompatImageView
对我不起作用。我已将其更改为 ImageView
。并将 getChildAt
更改为 findViewById
。
我还隐藏了所有未选中项目的标签。
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);
}
}
}
1. 在menu/abc中设置android:title="";
.xml
2. 创建以下使用反射
的助手 class
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. 在您的主 activity 中,添加以下行:
mBottomNav = (BottomNavigationView) findViewById(R.id.navigation);
BottomNavigationViewHelper.disableShiftMode(mBottomNav);
我想删除 和标签,none 这里的解决方案对我来说效果很好,所以这是我根据我在这里学到的一切构建的解决方案:
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。
希望我来这里聚会还不算太晚。
但截至设计支持库 28.0.0-alpha1
你可以使用 属性
app:labelVisibilityMode="unlabeled"
您也可以使用其他值 "auto"、"labeled" 和 "selected"。
Google 发布了带有 BottomNavigationView 的新支持库 v25
有什么方法可以删除项目标签吗?
不幸的是,第一个版本的 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。添加到layout.xml这个customView
有关详细信息,我已在 Github
上实现了此功能无反射方法:
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"
这将使它无论背景颜色是什么,都显示为禁用。它确实使图标看起来更高。
你想要这种风格吗?
如果是这样,我建议您尝试 BottomNavigationViewEx。
我建议您自己实现 AppCompatImageView
对我不起作用。我已将其更改为 ImageView
。并将 getChildAt
更改为 findViewById
。
我还隐藏了所有未选中项目的标签。
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);
}
}
}
1. 在menu/abc中设置android:title="";
.xml
2. 创建以下使用反射
的助手 classimport 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. 在您的主 activity 中,添加以下行:
mBottomNav = (BottomNavigationView) findViewById(R.id.navigation);
BottomNavigationViewHelper.disableShiftMode(mBottomNav);
我想删除
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。
希望我来这里聚会还不算太晚。
但截至设计支持库 28.0.0-alpha1 你可以使用 属性
app:labelVisibilityMode="unlabeled"
您也可以使用其他值 "auto"、"labeled" 和 "selected"。