Background color change in BottomNavigationView

前端 未结 5 1235
轻奢々
轻奢々 2020-12-13 18:43

I have implemented BottomNavigationView which is available from the new support library 25.0.0. Here is my code for that



        
相关标签:
5条回答
  • 2020-12-13 18:59

    Try this it is a sample code of navigation item select listener. hope it helps you.

     @Override
      public boolean onNavigationItemSelected(final MenuItem menuItem) {
        // update highlighted item in the navigation menu
        menuItem.setChecked(true);
        mNavItemId = menuItem.getItemId();
    
        // allow some time after closing the drawer before performing real navigation
        // so the user can see what is happening
        mDrawerLayout.closeDrawer(GravityCompat.START);
        mDrawerActionHandler.postDelayed(new Runnable() {
          @Override
          public void run() {
            navigate(menuItem.getItemId());
          }
        }, DRAWER_CLOSE_DELAY_MS);
        return true;
      }
    

    Alternative solution:

    Make a drawable file highlight_color.xml with following contents :

    <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
         <solid android:color="YOUR HIGHLIGHT COLOR"/>
    </shape>
    

    Make another drawable file nav_item_drawable.xml with following contents:

    <selector xmlns:android="http://schemas.android.com/apk/res/android">
            <item android:drawable="@drawable/highlight_color" android:state_checked="true"/>
    </selector>
    

    Finally add app:itemBackground tag in the NavView :

    <android.support.design.widget.NavigationView
    android:id="@+id/activity_main_navigationview"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    app:headerLayout="@layout/drawer_header"
    app:itemIconTint="@color/black"
    app:itemTextColor="@color/primary_text"
    app:itemBackground="@drawable/nav_item_drawable"
    app:menu="@menu/menu_drawer">
    

    here the highlight_color.xml file defines a solid color drawable for the background. Later this color drawable is assigned to nav_item_drawable.xml selector.

    Try this one.

    0 讨论(0)
  • 2020-12-13 19:04

    I encountered a similar problem to the OP's, but a little different. If you put sth like@color/color_selector into the BottomNavigationView's app:itemBackground="___". It will cause the view to hide in design panel, and the app to crush when launching. Though it works fine if your just set it to a constant color like @color/black.

    For a more in-depth explanation, I dug into android api reference. Now I think I have found the answer that can reasonably resolve this problem. (May not accurate.)

    The problem is, what you provide are NOT EXACTLY what they asked for.

    app:itemIconTint and app:itemTextColor ask for a hex color, while app:itemBackground asks for a literally Drawable. The <color> elements we write in colors.xml are ColorDrawable. It's derived from Drawable so it can feed all three attributes.

    However, when you change it to use a selector, things become different. Both hex color and drawable have a corresponding selector. A selector acts like the resource you put in, but the outcome is not the original one. It's more like a single-purpose wrapper. You can't feed a hex color to an attribute who requires a Drawable.

    The color selector is actually a ColorStateList, provides a hex color, resides in res/color. You can use only the attribute android:color in this file. it will prompt an error if you write android:drawable.
    The drawable selector is StateListDrawable, provides Drawable, resides in res/drawable. You should write android:drawable here, but there is no error if you write android:color.

    However android:color only provides a hex color that can't be recognized as a Drawable, while app:itemBackground requires a Drawable, so the app is doomed. (Direct cause)

    Both attribute (android:color and android:drawable) accept a ColorDrawable, here it works just like when you set a constant color.

    The solution (and the practice) is:

    • Use (and only) android:drawable in a res/drawable/drawable_selector.xml. Example:

      <?xml version="1.0" encoding="utf-8"?>
      <selector xmlns:android="http://schemas.android.com/apk/res/android">
          <item android:drawable="@color/colorAccent" android:state_checked="true" />
          <item android:drawable="@color/colorAccentDark" />
      </selector>
      
    • Use res/color/color_selector.xml when it needs a hex color (to avoid confusing). Example:

      <?xml version="1.0" encoding="utf-8"?>
      <selector xmlns:android="http://schemas.android.com/apk/res/android">
          <item android:color="@android:color/white" android:state_checked="true"/>
          <item android:color="@color/colorPrimary" />
      </selector>
      
    • Provide app:itemBackground with drawable. Example:

      <android.support.design.widget.BottomNavigationView
          ...
          app:itemBackground="@drawable/drawable_selector"
          app:itemIconTint="@color/color_selector"
          app:itemTextColor="@color/color_selector"
          ... />
      

    (Worth noting that if you are using Android Studio, its auto-completion feature will tell you what attributes are legal and available, and it doesn't suggest you android:color in a selector under res/drawable!)

    0 讨论(0)
  • 2020-12-13 19:04

    first create xml bottom_navigation_items with

    <ripple xmlns:android="http://schemas.android.com/apk/res/android"
        android:color="?android:colorControlHighlight">
        <item>
            <selector>
                <item
                    android:drawable="@color/primary_bottom_select"
                    android:state_checked="true" />
                <item
                    android:drawable="@color/bottom_navigation"
                    android:state_checked="false" />
            </selector>
        </item>
    </ripple>
    

    second: add app:itemBackground="@drawable/bottom_navigation_items"

    0 讨论(0)
  • 2020-12-13 19:10

    found an answer from this medium post

    1. We need to use android:state_checked instead of android:state_enabled
    2. within onNavigationItemSelected you need to use return true instead of return false.

    and to set background, we cannot use android:color in <item>, we need to use android:drawable

    So here how it looks xml file when you are setting it for app:itemTextColor and app:itemIconTint

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:color="@color/colorPrimaryDark" android:state_checked="true" />
        <item android:color="@android:color/white" android:state_checked="false" />
    </selector>
    

    and to set app:itemBackground selector

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:drawable="@drawable/banner_white" android:state_checked="true"/>
        <item android:drawable="@drawable/banner_green" android:state_checked="false"/>
    </selector>
    

    Here banner_white and banner_green are pngs.

    0 讨论(0)
  • 2020-12-13 19:13

    An easy way worked for me:

    <BottomNavigationView
    ...
    android:theme="@style/CustomTheme"/>
    
    <style name="CustomTheme">
       <item name="android:background">@color/colorPrimary</item>
    </style>
    
    0 讨论(0)
提交回复
热议问题