Reputation: 325
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 ?
Upvotes: 13
Views: 2513
Reputation: 4219
The issue seems to be fixed in Material Components 1.1.0, but it is currently in alpha.
Tried with:
implementation com.google.android.material:material:1.1.0-alpha10
Upvotes: 1
Reputation: 866
I am having the same issue when the activity goes into onPause then onResume I was calling setImageResource
on the FloatingActionButton
. The FAB icon was disappearing. My solution was to call the following right after setImageResource
mFloatingActionButton.hide();
mFloatingActionButton.show();
Upvotes: 20
Reputation: 1791
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
Upvotes: 14
Reputation: 91
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.
Upvotes: 4