Search code examples
androidfloating-action-buttonandroid-navigation-barandroid-bottomnavigationview

Dynamically change the FAB in MainActivity for Android


I have the following XML layout

<androidx.coordinatorlayout.widget.CoordinatorLayout
    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=".MainActivity">

    <FrameLayout
        android:id="@+id/fragment_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />


    <com.google.android.material.bottomappbar.BottomAppBar
        android:id="@+id/bottomAppBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:fabCradleMargin="20dp"
        app:fabCradleVerticalOffset="10dp"
        app:fabCradleRoundedCornerRadius="20dp"
        android:layout_gravity="bottom">

        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/bottomNavigationView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginEnd="16dp"
            android:background="@android:color/transparent"
            app:menu="@menu/bottom_nav_menu" />

    </com.google.android.material.bottomappbar.BottomAppBar>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_anchor="@id/bottomAppBar" />


</androidx.coordinatorlayout.widget.CoordinatorLayout>

The associated Java file is the following:

public class MainActivity extends AppCompatActivity {

    BottomNavigationView bottomNavigationView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        bottomNavigationView = findViewById(R.id.bottomNavigationView);


        FloatingActionButton fab = findViewById(R.id.fab);
      
        fab.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                
                Snackbar.make(view, "Here's a Snackbar", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
            

        }

    });

}

My question is, I would like to assign an image source dynamically as well as an action based on which of the navigation fragment the user is on.

So when the app opens it would default to the fab button having a '+' which allows users to add items to list.

If they hit the setting nav button I would like for the image to be gear and if pressed it opens the user setting prefs.

I am just not sure how to achieve this?

UPDATE:

if (bottomNavigationView.getMenu().findItem(R.id.miHome).isChecked()) {

    // Set icon image for FAB
    fab.setImageResource(R.drawable.ic_add);

} else if (bottomNavigationView.getMenu().findItem(R.id.miSettings).isChecked()) {

    fab.setImageResource(R.drawable.ic_settings);

    fab.setBackgroundColor(Color.RED);

}

The behavior is that it will show the + sign on load, since the dashboard is the default at app launch, but when I hit the settings nav button, the FAB icon does NOT change to the gear and the background color does NOT turn red!?

Can anyone advise what I am doing wrong?


Solution

  • Using if (bottomNavigationView.getMenu().findItem(R.id.miHome).isChecked()) condition will be triggered only once, but you need to register a listener to the lifetime of the lifecycle owner of the bottomNavigationView which is the MainActivity.

    This is typically the OnNavigationItemSelectedListener

    bottomNavigationView.setOnNavigationItemSelectedListener(
            new BottomNavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                    if (item.getItemId() == R.id.miHome) {
                        fab.setImageResource(R.drawable.ic_add);
                        
                    } else if (item.getItemId() == R.id.miSettings) {
                        fab.setImageResource(R.drawable.ic_settings);
                        fab.setBackgroundColor(Color.RED);
                    }
                    return true;
                }
            });