Usuń etykiety BottomNavigationView


85

Firma Google udostępniła nową bibliotekę wsparcia v25 z BottomNavigationView

wprowadź opis obrazu tutaj

czy istnieje sposób na usunięcie etykiet produktów?


1
Czy próbowałeś usunąć titles z menu <item>?
Mike M.

8
Po usunięciu tytułów pod ikonami pojawia się dodatkowe wypełnienie. Dodanie layout_marginBottom="-16dp"usunie to wypełnienie, ale zmniejszy cały widok.
dzikovskyy

Możesz zamiast ustawiać marginesy, ustawić niestandardową wysokość i dodać dodatkowe wypełnienie u góry. W ten sposób możesz wyśrodkować ikony.
Bolling

4
Po prostu naprawiłem to w ten sposób: android:paddingTop="8dp" android:layout_marginBottom="-8dp" To zapobiega zmniejszaniu się paska
Palm

Odpowiedzi:


206

Mam nadzieję, że nie jestem za późno na imprezę tutaj.

Jednak od wersji 28.0.0-alpha1 Design Support Library można używać tej właściwości

app:labelVisibilityMode="unlabeled"

BottomNavigationView bez etykiet

możesz także użyć innych wartości „auto”, „labeled” i „selected”.


która biblioteka wsparcia? v7 czy projekt?
Sagar Maiyad,

biblioteka wsparcia projektowania 28.0.0
Abdul-Aziz-Niazi

najbardziej oczekiwana funkcja.
bikram,

1
Na jakiej klasie to piszesz?
Explorex

1
@Explorex To jest dolny widok nawigacji Androida, a atrybuty, o których wspomniałem, to atrybuty XML wspomnianej klasy używane w tagu xml wspomnianego widoku. możesz go też użyć w kodzie developer.android.com/reference/com/google/android/material/…
Abdul-Aziz-Niazi

22

Chcesz tego stylu?

Jeśli tak, polecam wypróbowanie BottomNavigationViewEx .


Nie lubię tej biblioteki. powoduje zmianę położenia ikony po kliknięciu i nie ma możliwości ustalenia pozycji ikony po kliknięciu.
Dika

18

Niestety ta pierwsza wersja BottomNavigationView miała wiele ograniczeń. Na razie nie możesz usunąć tytułów po prostu za pomocą interfejsu API projektowania wsparcia. Aby rozwiązać to ograniczenie, gdy Google go nie implementuje, możesz zrobić (używając refleksji):

1. Ustaw tytuły puste w pliku bottom_navigation_menu.xml.

2. Rozszerza 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. Dodaj do layout.xml ten customView

Aby uzyskać więcej informacji, zaimplementowałem to na Github


Nie musisz używać refleksji, możesz je uzyskać BottomNavigationItemView, wywołując findViewById()z menu ids (tak jak @NikolaDespotoski robi w swojej odpowiedzi ).
Fred Porciúncula

1
Obsługują usuwanie etykiet terazapp:labelVisibilityMode="unlabeled"
Amjad Alwareh

13

1. Ustaw android:title="";w menu / abc.xml

2. Utwórz poniższą klasę pomocniczą, która używa refleksji

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. W swoim głównym działaniu dodaj następujące wiersze:

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

11

Bezrefleksyjne podejście:

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
A może chcę usunąć ikonę zamiast tekstu
Merhawi Fissehaye

Jak mogę to nazwać w głównym działaniu, w którym domyślny kod BottomNavigation już istnieje? @NikolaDespotoski
TiagoIB

@TiagoIB po prostu ustaw metodę jako statyczną i przenieś ją do innej klasy. Lub zachowaj go jako prywatny i wywołaj go z określonymi argumentami.
Nikola Despotoski

Przepraszam, ale jak mogę wstawić to do mojego kodu? prntscr.com/he03j7 @NikolaDespotoski
TiagoIB

6

To jest tymczasowe rozwiązanie. Po prostu dodaj: app:itemTextColor="@android:color/transparent"to sprawi, że niezależnie od koloru tła będzie wyglądać na wyłączone. To sprawia, że ​​ikona wygląda na podniesioną.


2

Chciałem usunąć zarówno animację zmiany biegów, jak i etykiety, ale żadne z rozwiązań tutaj nie działało dobrze, więc oto jedno, które zbudowałem w oparciu o wszystko, czego się tutaj nauczyłem:

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

Po prostu dodaj tę metodę do swojego własnego BottomNavigationViewi nazwij ją przekazując identyfikatory pozycji menu.


1

Poleciłbym zaimplementować to samodzielnie, jak podał sanf0rd w swojej odpowiedzi . Ale AppCompatImageViewto nie działa dla mnie. Zmieniłem to na ImageView. I zmieniono getChildAtna findViewById.

Ukrywam również wszystkie etykiety niewybranych elementów.

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);
        }
    }
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.