preface

BottomNavigationView is an implementation of a standard bottom navigation bar provided by Material Design, which can easily switch and browse between navigation bar menus. Bottom navigation makes it easier for users to view and switch the top navigation interface. It is suitable for three to five tabs.

In the navigation column at the bottom of the APP, users are prompted with new messages and the specific number of messages is displayed at the bottom of the navigation bar. This effect has been applied in all mainstream apps. This paper introduces that BottomNavigationView + ViewPager + Fragment + BadgeView can achieve the effect of wechat message corner mark and QQ message drag effect.


BottomNavigationView related attributes

methods introduce
setSelectedItemId(int itemId) Sets the ID of the selected menu item
setElevation(float elevation) Sets the base elevation of this view in pixels
setItemBackground(Drawable background) Sets the background of the menu item to the given drawable object
setItemBackgroundResource(int resId) Sets the background of the menu item to the given resource
setItemIconSize(int iconSize) Set the size to provide menu item ICONS
setItemIconTintList(ColorStateList tint) Sets the color applied to the menu item icon
setItemRippleColor(ColorStateList itemRippleColor) Sets the background of a menu item to a ripple of the given color
setItemTextAppearanceActive(int textAppearanceRes) Sets the text styles used for menu item labels
setItemTextAppearanceInactive(int textAppearanceRes) Sets text styles for inactive menu item labels
setItemTextColor(ColorStateList textColor) Sets the color to be used for different states of menu item text (normal, selected, focused, etc.)
setLabelVisibilityMode(int labelVisibilityMode) Sets the TAB visibility mode for the navigation item
setItemHorizontalTranslationEnabled(boolean itemHorizontalTranslationEnabled) Sets whether menu items pan horizontally when selected when the merged item widths fill the screen
setOnNavigationItemReselectedListener(BottomNavigationView.OnNavigationItemReselectedListener listener) Sets a listener to be notified when the currently selected bottom navigation item is re-selected
getMenu() Returns to the Menu instance associated with this bottom navigation bar
getMaxItemCount() Returns the maximum number of menus
  • SetSelectedItemId (int itemId) Sets the ID of the selected menu item.

  • SetElevation (float elevation) sets the base elevation, in pixels, of this view.

  • SetItemBackground (Drawable Background) sets the background of the menu item to the given Drawable object.

  • SetItemBackgroundResource (int resId) set the background of the menu item to a given resource.

  • SetItemIconSize (int iconSize) Sets the size to provide menu item ICONS.

  • SetItemIconTintList (ColorStateList tint) Sets the color applied to the menu item icon.

  • SetItemRippleColor (ColorStateList itemRippleColor) sets the background of a menu item to a ripple with a given color.

  • SetItemTextAppearanceActive (int textAppearanceRes) set used for the text style menu item labels.

  • SetItemTextAppearanceInactive (int textAppearanceRes) Settings for the inactive menu item label text style.

  • SetItemTextColor (ColorStateList textColor) sets the color used for the different states of the menu item text (normal, selected, focused, etc.).

  • SetLabelVisibilityMode (int labelVisibilityMode) sets the labelVisibilityMode for the navigation item.

  • SetItemHorizontalTranslationEnabled (Boolean itemHorizontalTranslationEnabled) set when merger projects width to fill the screen, whether the menu item when the choice translation level.

  • SetOnNavigationItemReselectedListener (BottomNavigationView OnNavigationItemReselectedListener listener) to set up a listener, The listener is notified when the currently selected bottom navigation item is re-selected.

  • SetOnNavigationItemSelectedListener (BottomNavigationView OnNavigationItemSelectedListener listener) to set up a listener, The listener is notified when the bottom navigation item is selected.

  • GetMenu () returns the instance of Menu associated with this bottom navigation bar.

  • GetMaxItemCount () returns the maximum number of menus.

Second, BottomNavigationView basic use

1. Dependency introduction

implementation 'com.google.android.material:material:1.0.0-alpha1'
Copy the code

2. XML layout file

Introduce controls directly into the XML layout file

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/bottomNavigationView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
 app:menu="@menu/activity_bottom_nav" />
Copy the code

Menu creation

BottomNavigationView needs to add a menu layout. In DarwerLayout+NavigationView, the BottomNavigationView needs to add a menu layout. The bottom navigation bar requires at least three attributes: Android: ID, Android :icon, and Android :title. I will not elaborate here, but directly attach the code:


      
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/menu_item_home"
 android:icon="@drawable/ic_vector_bottom_home"  android:title="Home page" />   <item  android:id="@+id/menu_item_project"  android:icon="@drawable/ic_vector_bottom_book"  android:title="Project" />   <item  android:id="@+id/menu_item_movie"  android:icon="@drawable/ic_vector_bottom_movie"  android:title="Film" /> </menu> Copy the code

4. More than three Tab text and animation effects

After the above three steps, you can basically see the display effect of the BottomNavigationView, but when more than three menus are found, the text display is abnormal and the animation effect changes. To solve this problem, in the latest version of the API, there is a solution that can be solved perfectly in one line of code.

bottomNavigationView.setLabelVisibilityMode(LABEL_VISIBILITY_LABELED);
// Or use attributes in XML files
app:labelVisibilityMode="labeled"
Copy the code

Since this article is based on androidx, if you need compatibility with older versions, use the following methods:

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);  // Remove the animation  item.setShiftingMode(false); / / API before 28  item.setChecked(item.getItemData().isChecked());  }  } catch (NoSuchFieldException e) {  LogUtils.e( "Unable to get shift mode field");  } catch (IllegalAccessException e) {  LogUtils.e( "Unable to change value of shift mode");  } } Copy the code

5. Set the color of the selected menu

1. Create a selector_nav_text_item. XML file in the color folder


      
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/white" android:state_checked="true"  />
    <item android:color="@color/white" android:state_pressed="true" />
    <item android:color="@color/md_grey_700"/>
</selector> Copy the code

2. Set the color properties

app:itemIconTint="@color/selector_nav_text_item"
app:itemTextColor="@color/selector_nav_text_item"
Copy the code

6. Set Item to select

// index indicates the TAB index
bottomNavigationView.getMenu().getItem(index).setChecked(true);
Copy the code

7. Set the selected listener

The BottomNavigationView sets up a listener that can click on the selected Item based on the ID of the Item. You can do a lot of things here, such as switching between ViewPager and Fragment, setting the Item style, and so on.

bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
        switch (menuItem.getItemId()) {
            case R.id.menu_item_home:
 Toast.makeText(BottomNavigationViewActivity.this."Home page", Toast.LENGTH_SHORT).show();  bottomNavigationView.setBackgroundColor(getResources().getColor(R.color.light_yellow));  break;  case R.id.menu_item_project:  Toast.makeText(BottomNavigationViewActivity.this."Project", Toast.LENGTH_SHORT).show();  bottomNavigationView.setBackgroundColor(getResources().getColor(R.color.brown));  break;  case R.id.menu_item_movie:  Toast.makeText(BottomNavigationViewActivity.this."Film", Toast.LENGTH_SHORT).show();  bottomNavigationView.setBackgroundColor(getResources().getColor(R.color.txt_link_blue));  break;  case R.id.menu_item_book:  Toast.makeText(BottomNavigationViewActivity.this."Dry", Toast.LENGTH_SHORT).show();  bottomNavigationView.setBackgroundColor(getResources().getColor(R.color.md_lime_700));  break;  case R.id.menu_item_personal:  Toast.makeText(BottomNavigationViewActivity.this."Personal", Toast.LENGTH_SHORT).show();  bottomNavigationView.setBackgroundColor(getResources().getColor(R.color.md_yellow_500));  break;  }  return true;  } }); Copy the code

BottomNavigationView + ViewPager + Fragment

BottomNavigationView is often used together with ViewPager and Fragment, which is the most basic framework structure in APP development. ViewPager Fragmemt is a Fragment that can be Fragmemt or ViewPager. Android Material Design series: TabLayout + ViewPager + Fragment

1, ViewPager slide sync BottomNavigationView

OnPageSelected (int Position) returns the position of the current page. Then through the above said bottomNavigationView. GetMenu (). The getItem (position). SetChecked (true); Method sets the currently selected item.

viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    }

 @Override  public void onPageSelected(int position) {  bottomNavigationView.getMenu().getItem(position).setChecked(true);  // TODO:Update ToolBar title bar  setToolBarTitle(position);  }   @Override  public void onPageScrollStateChanged(int state) {   } }); Copy the code

BottomNavigationView toggle sync ViewPager

Similarly, listen to BottomNavigationView to select the interface, and in the callback method onNavigationItemSelected(MenuItem MenuItem) update the ViewPager TAB according to the ItemID, This is done by calling the viewpager.setcurrentitem () method;

bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
        switch (menuItem.getItemId()) {
            case R.id.menu_item_home:
 Toast.makeText(BottomNavigationViewActivity.this."Home page", Toast.LENGTH_SHORT).show();  viewPager.setCurrentItem(0.false);  break;  case R.id.menu_item_project:  Toast.makeText(BottomNavigationViewActivity.this."Project", Toast.LENGTH_SHORT).show();  viewPager.setCurrentItem(1.false);  break;  case R.id.menu_item_movie:  Toast.makeText(BottomNavigationViewActivity.this."Film", Toast.LENGTH_SHORT).show();  viewPager.setCurrentItem(2.false);  break;  case R.id.menu_item_book:  Toast.makeText(BottomNavigationViewActivity.this."Dry", Toast.LENGTH_SHORT).show();  viewPager.setCurrentItem(3.false);  break;  case R.id.menu_item_personal:  Toast.makeText(BottomNavigationViewActivity.this."Personal", Toast.LENGTH_SHORT).show();  viewPager.setCurrentItem(4.false);  break;  }  return true;  } }); Copy the code

3. Set the Toolbar title bar

In general, the title bar of each APP interface is different. To facilitate the management of all toolbars in MainActivity, set the ToolBar title bar dynamically according to the ViewPager listener callback method. The call code has been posted in the ViewPager slide sync BottomNavigationView directory, with the update ToolBar method attached.

/ * ** Update Toolbar title * @param currentTitleIndex
* /
private void setToolBarTitle(int currentTitleIndex) {
 toolbar.setTitle(bottomNavigationView.getMenu().getItem(currentTitleIndex).getTitle()); } Copy the code

Four, BadgeView introduction

1, define,

A MaterialDesign-style Android BadgeView that allows you to customize the look and feel freely and support drag and drop elimination

2, features,

  • Customize the appearance at will, including Badge position, background color, border, shadow, text color (transparent color support), size, inside and outside margin, etc

  • Badge number less than 0 display dot, equal to 0 hide the entire Badge, in normal mode over 99 display 99+, precise mode display specific value

  • Supports setting text content

  • Supports setting image background

  • Support similar to QQ drag elimination effect (default off)

  • Support for hiding the Badge in an animated manner


BadgeView method description

methods introduce
getBadgeNumber Set Badge number
setBadgeText Set Badge text
setBadgeTextSize Set the Badge text font size
setBadgeTextColor Set the Badge text font color
setBadgeGravity Set the Badge in the TargetView location
setExactMode Sets whether to display the exact numeric mode
setGravityOffset Set margins
setBadgePadding Set the inside margin
setBadgeBackgroundColor Set the background color
setBadgeBackground Setting the background image
setShowShadow Sets whether to display a shadow effect
stroke stroke
hide Hide the Badge
setOnDragStateChangedListener Enable drag elimination and listen

BottomNavigationView + BadgeView

1. Dependency package introduction

implementation 'q.r orbin: badgeview: 1.1.3'
Copy the code

Get BottomNavigationMenuView

Badge needs to be bound to a View, and all methods and operations are centered around this View. Since we’re talking about the BottomNavigationView, we’ll center on the MenuItemView of the BottomNavigationView.

If you look at the source, you can see that BottomNavigationMenuView is a child View that’s added inside of BottomNavigationView, which means it’s a parent View of all the menus that are added in the navigation bar, So it’s easy to get the BottomNavigationMenuView and the submenu.

BottomNavigationMenuView itemView = (BottomNavigationMenuView) bottomNav.getChildAt(0);
// Get the number of navigation tabs
int childCount = itemView.getChildCount();
Copy the code

3. Initialize BadgeView

Badge is an interface that creates an implementation class QBadgeView object and then sets the related properties.

QBadgeView qBadgeView=new QBadgeView(context);
Copy the code

4, BadgeView basic usage

BadgeView Sets the binding View, number, and position

new QBadgeView(getActivity()).bindTarget(itemView.getChildAt(0))
        .setBadgeNumber(6)
        .setBadgeGravity(Gravity.TOP | Gravity.END);
Copy the code

5. Modify the text color

new QBadgeView(getActivity()).bindTarget(itemView.getChildAt(1))
        .setBadgeNumber(27)
        .setBadgeGravity(Gravity.TOP | Gravity.END)
        .setBadgeTextColor(Color.YELLOW)
        .setGravityOffset(10.0.true);
Copy the code

6. Set whether to exact mode number

SetExactMode (Boolean isExact) Set this parameter to false. When the number of messages is greater than 99, 99+ is displayed. When the number of messages is greater than 99, the specific number of messages is displayed.

/ / show 99 +
new QBadgeView(getActivity()).bindTarget(itemView.getChildAt(2))
        .setBadgeNumber(999)
        .setBadgeGravity(Gravity.TOP | Gravity.END)
        .setExactMode(false);
/ / show 1000 new QBadgeView(getActivity()).bindTarget(itemView.getChildAt(3))  .setBadgeNumber(1000)  .setBadgeGravity(Gravity.TOP | Gravity.END)  .setExactMode(true); Copy the code

BadgeView Shadow effect

SetShowShadow (Boolean showShadow) setShowShadow(Boolean showShadow) sets the showShadow method to true, and cancels the shadow method to false.

new QBadgeView(getActivity()).bindTarget(itemView.getChildAt(4))
        .setBadgeNumber(9)
        .setBadgeGravity(Gravity.TOP | Gravity.END)
        .setBadgeBackgroundColor(Color.BLUE)
        .setShowShadow(false);
Copy the code

BadgeView drag effect

BadgeView add setOnDragStateChangedListener listening, imitation QQ drag effect can be realized, this paper used on BottomNavigationView navigation Item, It can also be realized on RecyclerView Item, which is extremely simple to use.

The onDragStateChanged callback has five dragState states:

  • int STATE_START = 1;
  • int STATE_DRAGGING = 2;
  • int STATE_DRAGGING_OUT_OF_RANGE = 3;
  • int STATE_CANCELED = 4;
  • int STATE_SUCCEED = 5;
new QBadgeView(getActivity()).bindTarget(itemView.getChildAt(4))
        .setBadgeNumber(9)
        .setBadgeGravity(Gravity.TOP | Gravity.END)
        .setOnDragStateChangedListener(new Badge.OnDragStateChangedListener() {
            @Override
 public void onDragStateChanged(int dragState, Badge badge, View targetView) {   }  }); Copy the code

The above just selected a few more commonly used attributes to explain in detail, if you are interested in other attributes can write a case to try.


Seven, BadgeView use precautions

  • Do not create a Badge in XML
  • Badge and TargetView binding is implemented by replacing the Parent TargetView. Set the Parent Id to be the same as the TargetView Id to ensure that the position within the RelativeLayout is not misaligned. Therefore, findViewById(TargetViewId) after bindTarget will get Parent instead of TargetView. It is recommended to obtain TargetView by badge. getTargetView.

Source code download contains Material Design series control set, regularly updated, please look forward to!

conclusion

When we first implemented the framework of the APP home page, most people were immersed in the world of Tablayout + Viewpager + Fragment. I believe some people still use RadioGroup and RadioButton. Since Google has provided BottomNavigationView control for developers, still using third-party controls and original mode friends, can rest assured to migrate over, Google produced, must be high-quality, with BadgeView perfect implementation of the bottom navigation bar.

Thank you so much for reading this article! Your praise and comments are the biggest motivation for my creation!

My WeChat: Jaynm888

Programmer interview networking group: 764040616

Android programmers are cordially invited to join the wechat communication group. The public account can reply to the wechat group or add my wechat invitation to join the group.