I have a bottom navigation view with 3 items which navigate to 3 different fragments (fragments are created only once and their instances are saved in mainactivity's onSavedInstanceState()) and on top of it a floating action button.
We want to change the icon drawable for the fab when each fragment is visited we tried both setImageResource()
and .setImageDrawable()
on the fab in a switch case when each bottom navigation icon is picked.
/**
* used to handle switching between fragments when a new navigation item is selected
*/
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.nav_tasks:
.........
loadFragment(tasksFragment);
mFab.setOnClickListener(mFabClickListenerTasks);
mFab.setImageDrawable(getResources().getDrawable(R.drawable.ic_add_task));
//2 tabs in 1 fragment
if (mTabLayout.getSelectedTabPosition() == 1)
mFab.hide();
else mFab.show();
break;
case R.id.nav_employees:
.......
loadFragment(employeesFragment);
mFab.setOnClickListener(mFabClickListenerEmployees);
mFab.setImageDrawable(getResources().getDrawable(R.drawable.ic_add_employee2));
mFab.show();
break;
case R.id.nav_departments:
.......
loadFragment(departmentsFragment);
mFab.setOnClickListener(mFabClickListenerDepartments);
mFab.setImageDrawable(getResources().getDrawable(R.drawable.ic_add_department));
mFab.show();
break;
}
item.setChecked(true);
return true;
}
void loadFragment(Fragment fragment) {
if (activeFragment == fragment)
return;
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.hide(activeFragment).show(fragment);
activeFragment = fragment;
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
if (activeFragment instanceof TasksFragment)
mFab.setImageResource(R.drawable.ic_add_task);
else if(activeFragment instanceof DepartmentsFragment)
mFab.setImageResource(R.drawable.ic_add_department);
else if(activeFragment instanceof EmployeesFragment)
mFab.setImageResource(R.drawable.ic_add_employee2);
transaction.commit();
}
The 3 fragments are mainly 3 recycler views, we also hide the fab when recyclerview scrolls.
The fab drawable will be set correctly when traversing the fragments from the bottom navigation , but in any fragment when we scroll it saves this state to return to it afterwards.
This removes the fab drawable when going to another fragment and leaves the fab empty with no icon drawable. How can we solve this ?
With the Navigation component, you can call the NavController 's navigate () method to swap the fragment that's displayed. The NavController also helps you handle common tasks like responding to the system "up" button to navigate back to the previously displayed fragment.
A FragmentContainerView is used to embed fragments in other activities and can manage navigation between fragments. Setting the navGraph attribute of a FragmentContainerView allows you to navigate between fragments within an activity.
As with a Toolbar, a variety of hooks/callbacks exist for attaching a BottomAppBar to an Activity or Fragment, inflating a menu and handling item clicks. To do so, you’ll need to be using the AndroidX AppCompatActivity and/or Fragment classes. You should also be using a *.NoActionBar app theme variant.
NOTE: Refer Android Setup BottomNavigationView With Jetpack Navigation UI (Kotlin). We shall create an Activity with BottomNavigationView which switches the main view the fragments. You can create a Bottom Navigation Activity using Android Studio wizard: File -> New -> Activity -> Bottom Navigation Activity.
In my case downgrading design lib wasn't posible for many reasons. MrStahlfelge's answer helped me to find solution:
public class MyNewFab extends FloatingActionButton {
private Matrix imageMatrix;
...
@Override
protected void onFinishInflate() {
super.onFinishInflate();
imageMatrix = getImageMatrix();
}
@Override
public void setImageResource(int resId) {
super.setImageResource(resId);
setImageMatrix(imageMatrix);
}
}
This works for me. Hope it will help the others facing same problem.
It's a bug in the FloatingActionButton class: When calling show(), imageMatrixScale is set to 0. A call to setImageResource() then just displays blank. It works before calling show().
The bug has been introduced in the design lib 28.0.0, it was working on v27.1.1. Downgrade to 27.1.1
EDIT: Google Issuetracker
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With