Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disappearing fab icon on navigation fragment change

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 ?

like image 225
Moamen Mohamed Avatar asked Aug 19 '18 16:08

Moamen Mohamed


People also ask

How do I change the fragment that is displayed?

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.

How do I navigate between fragments in a fragmentcontainerview?

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.

How do I add a bottomappbar to an activity or fragment?

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.

How to setup bottomnavigationview with Jetpack navigation UI?

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.


Video Answer


2 Answers

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.

like image 129
Paweł Galiński Avatar answered Oct 17 '22 03:10

Paweł Galiński


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

like image 29
MrStahlfelge Avatar answered Oct 17 '22 03:10

MrStahlfelge