Reputation: 2189
I want my users to be able to change the (color) theme of my App. So we create multiple themes.
<resources>
<!-- First Theme -->
<style name="themeOne" parent="Theme.AppCompat.NoActionBar">
<item name="colorPrimary">@color/themeOneColorPrimary</item>
<item name="colorPrimaryDark">@color/themeOneColorPrimaryDark</item>
<item name="colorAccent">@color/themeOneAccent</item>
<item name="android:background">@color/themeOneBackground</item>
...
</style>
<!-- Second Theme -->
<style name="themeTwo" parent="Theme.AppCompat.Light.NoActionBar">
...
</style>
Now I want to change the looks of the BottomNavigationView. But cannot find an example on how to do so.
<android.support.design.widget.BottomNavigationView
android:id="@+id/nav_bottom"
app:menu="@menu/nav_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"/>
But I want to set the following depending on the Theme:
app:itemBackground="@color/colorPrimary"
app:itemIconTint="@color/white"
app:itemTextColor="@color/white"
Upvotes: 1
Views: 7376
Reputation: 1
I also encountered the terror of Google in relation to the bottom menu. I needed support for 5 different themes, with different colors, which I got from Google's Material 3 website. And all the colors changed, except for the lower menu, as well as the status of the bar and NavigationBar
. The task was complicated by the fact that the color change should occur in the fragment. Recreate()
doesn't work, so I went a little different way. If you need to change the color of the status bar and Navigation Bar, then pass them the color
variables or create a new TypedValue
similarly.Perhaps the code can be simplified, but I do not know how.
Started_Activity started_activity = (Started_Activity) getActivity();
// Replace the current fragment with a new instance of the Settings class
started_activity.getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container_main, Settings.class.newInstance()).commit();
// Create TypedValue objects to hold resolved attribute values
TypedValue typedValue = new TypedValue();
TypedValue typedValueText = new TypedValue();
// Resolve the colorSurfaceVariant and colorPrimary attributes from the current theme
started_activity.getTheme().resolveAttribute(R.attr.colorSurfaceVariant, typedValue, true);
started_activity.getTheme().resolveAttribute(com.google.android.material.R.attr.colorPrimary, typedValueText, true);
// Get the resolved color values
int color = typedValue.data;
int colorText = typedValueText.data;
// Find the BottomNavigationView and set its background and text colors
BottomNavigationView bottomNavigationView = started_activity.findViewById(R.id.bottom_navigation);
ColorStateList colorStateList = ColorStateList.valueOf(colorText);
bottomNavigationView.setBackgroundColor(color);
bottomNavigationView.setItemTextColor(colorStateList);
bottomNavigationView.setItemIconTintList(colorStateList);
This is what my color change looks like after clicking the corresponding button. First before, then after.T The colors are the official Google palette, taken from here https://m3.material.io/theme-builder#/custom
Upvotes: 0
Reputation: 2428
this isn't quite the answer you were looking for, but as I was trying to do the same thing with no success I found a workaround, so by making your themes in styles.xml inherit from material components (if they arent quite right you can use the .bridge to make them more like appcompat themes) you can change the background of the bottom nav so for instance my yellow theme
<style name="MyAppYellowTheme" parent="Theme.MaterialComponents.Light.Bridge">
<item name="colorPrimary">@color/primary_yellow</item>
<item name="colorPrimaryDark">@color/primary_dark_yellow</item>
<item name="colorAccent">@color/accent_yellow</item>
<item name="android:textColorPrimary">@color/primary_text_yellow</item>
<item name="android:colorBackground">@color/background_light</item>
<item name="tabLayoutStyle">@style/Yellow.TabLayout</item>
</style>
will make my bottom nav background color = colorPrimary if i add a material style to it like this
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Widget.MaterialComponents.BottomNavigationView.Colored"
app:layout_constraintBottom_toBottomOf="parent"
app:menu="@menu/navigation" />
there are different versions of this style that can be found here this works but you will still need to do something for the icons and text so i have a switch statement and based on the color, (dark or light) i switch the color state list like this
ColorStateList colorStateList = getBottomNavColor(theme, getActivity());
navigationView.setItemIconTintList(colorStateList);
navigationView.setItemTextColor(colorStateList);
getBottomNavController
private ColorStateList getBottomNavColor(String theme, Context context){
switch (theme) {
case Constants.THEME_BLUE:
return ContextCompat.getColorStateList(context,R.drawable.bottom_nav_selector_blue);
case Constants.THEME_YELLOW:
return ContextCompat.getColorStateList(context,R.drawable.bottom_nav_selector_yellow);
case Constants.THEME_GREEN:
return ContextCompat.getColorStateList(context,R.drawable.bottom_nav_selector_green);
case Constants.THEME_RED:
return ContextCompat.getColorStateList(context,R.drawable.bottom_nav_selector_red);
case Constants.THEME_PURPLE:
return ContextCompat.getColorStateList(context,R.drawable.bottom_nav_selector_purple);
case Constants.THEME_PINK:
return ContextCompat.getColorStateList(context,R.drawable.bottom_nav_selector_pink);
}
return ContextCompat.getColorStateList(context,R.drawable.bottom_nav_selector_blue);
}
again not what you or I were looking for but does work and could be worse, hope it helps
Upvotes: 3
Reputation: 108
I believe this should work
<style name="BottomNavTheme" parent="Widget.Design.BottomNavigationView">
<item name="app:itemBackground">@color/colorPrimary</item>
<item name="app:itemIconTint=">@color/white</item>
<item name="app:itemTextColor=">@color/white</item>
</style>
Then add to your XML
android:theme="@style/BottomNavTheme"
You can also use to Java change the style of the items individually for example
private Menu myMenu;
BottomNavigationView menu = findViewById(R.id.your_menu_id);
myMenu = menu.getMenu();
myMenu.findItem(R.id.your_menu_item_id).setIcon(R.drawable.your_new_icon);
myMenu.findItem(R.id.your_menu_item_id).setTitle("some text");
Upvotes: 1