Reputation: 388
I am trying to make a custom bottom navigation in android. I wanted to disable the shift and to given custom colors for icons. The icons are initially grey color and the selected one turns blue. The problem is that all images stay grey even if they are selected.
I tried to mess with some of it but nothing is making the buttons change color when selected.
Below is the code I tried.
This is the main activity java
public class admin extends AppCompatActivity {
BottomNavigationView bottomNavigationView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_admin);
bottomNavigationView = (BottomNavigationView) findViewById(R.id.navigation);
BottomNavigationViewHelper.disableShiftMode((bottomNavigationView));
bottomNavigationView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
bottomNavigationView.setItemIconTintList(null);
urgent urgentfragment = urgent.newInstance();
setFragment(urgentfragment,false);
}
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.bottom_urgent:
urgent urgentfragment = urgent.newInstance();
setFragment(urgentfragment,false);
return true;
case R.id.bottom_all:
all allfragment = all.newInstance();
setFragment(allfragment,false);
item.setChecked(true);
return true;
case R.id.bottom_attendedto:
attendedto attendedtofragment = attendedto.newInstance();
setFragment(attendedtofragment,false);
item.setChecked(true);
return true;
}
return false;
}
};
public void setFragment(Fragment fragment, boolean addtobackstack) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.event_framelayout, fragment);
if(!addtobackstack)
{
for(int i=0;i< fragmentManager.getBackStackEntryCount();++i)
fragmentManager.popBackStack();
}
else
{
fragmentTransaction.addToBackStack(null);
}
fragmentTransaction.commit();
}
}
This is the main activity xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".admin">
<FrameLayout
android:id="@+id/event_framelayout"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@+id/navigation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<android.support.design.widget.BottomNavigationView
android:id="@+id/navigation"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/navigation"
app:itemIconTint="@color/colors_bottom_navigation"
app:itemTextColor="@color/colors_bottom_navigation"
app:itemBackground="@color/colorPrimaryDark"/>
</android.support.constraint.ConstraintLayout>
This is the helper class that helps disabling the shift
package com.prototypeapp.healer.healer.customviews;
import android.annotation.SuppressLint;
import android.support.design.internal.BottomNavigationItemView;
import android.support.design.internal.BottomNavigationMenuView;
import android.support.design.widget.BottomNavigationView;
import android.util.Log;
import java.lang.reflect.Field;
public class BottomNavigationViewHelper {
@SuppressLint("RestrictedApi")
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);
// 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);
}
}
}
Upvotes: 1
Views: 3191
Reputation: 54194
You can have the appearance of color-changing icons by using a State List Drawable resource with PNG images. Let's imagine that you have two differently-colored PNGs:
res/drawable-mdpi/ic_share_black_24dp.png
res/drawable-mdpi/ic_share_blue_24dp.png
You'd then create the State List Drawable, using the checked state for the blue icon:
res/drawable/ic_share.xml
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_checked="true"
android:drawable="@drawable/ic_share_blue_24dp"/>
<item
android:drawable="@drawable/ic_share_black_24dp"/>
</selector>
Now, when you use ic_share
as the icon for a menu item in your BottomNavigationView
's menu, you'll see that the color changes.
Upvotes: 0
Reputation: 54194
You can achieve this by combining a Vector Drawable with a Color State List resource.
The first step is to create the color state list resource, using the checked state for the color you want when the bottom navigation item is selected. Here's one using blue and gray:
res/color/share_color.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#0000ff" android:state_checked="true" />
<item android:color="#1b1b1b" />
</selector>
With that in place, you can use this color state list as the color for your vector drawable:
res/drawable/ic_share.xml
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="@color/share_color"
android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z" />
</vector>
Now, when you use ic_share
as the icon for a menu item in your BottomNavigationView
's menu, you'll see that the color changes.
Note that this requires that you use the Support Library for vector drawables (as opposed to build-time PNG generation).
Upvotes: 0