1

I am using a BottomNavigationDrawer/BottomSheetDialog from the following example, but I am unable to set the text and background color for the selected item in my bottom navigation menu.

I have tried the following SO questions' solutions but there seems to be no effect at all, and my menus all show up in colorPrimary (black) on a menu background color (white), with no separator or indicator that an item has been selected.

I have tried this question, this one, this one, this one and this one, all to no avail.

Can anyone point out to me what I am doing wrong? At this time, my code is as follows:

BottomSheetDialogFragment

public class BottomNavigationDrawerFragment extends BottomSheetDialogFragment {

    BottomNavigationDrawerFragment fragment;
    NavigationView navigationView;
    ImageView close, menu;
    Statuser statuser;
    RevivDatabase database;
    String email, fname, lname;
    TextView txtUsername, txtEmail;

    public BottomNavigationDrawerFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view =  inflater.inflate(R.layout.fragment_bottomsheet, container, false);
        txtUsername = view.findViewById(R.id.txtUsername);
        txtEmail = view.findViewById(R.id.txtEmail);
        navigationView = view.findViewById(R.id.navigation_view);
        database = RevivDatabase.getDatabase(getActivity());
        statuser = database.revivDao().getUserDetails();
        fname = statuser.getFname();
        lname = statuser.getLname();
        email = statuser.getEmail();
        txtEmail.setText(email);
        txtUsername.setText(fname+" "+lname);
        close = view.findViewById(R.id.imgClose);
        fragment = this;
        close.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                fragment.dismiss();
            }
        });

        navigationView.setItemIconTintList(null);
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
                menuItem.setChecked(true);
                int id = menuItem.getItemId();

                switch (id){
                    case R.id.app_bar_incident:
                        navigationView.getMenu().findItem(id).setChecked(true);
                        getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.containerFrameLayout, new FragmentRevivIncidentDashboard()).commit();
                        fragment.dismiss();
                        break;
                    case R.id.app_bar_housecall:
                        navigationView.getMenu().findItem(id).setChecked(true);
                        getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.containerFrameLayout, new FragmentRevivHousecallDashboard()).commit();
                        fragment.dismiss();
                        Toast.makeText(getContext(), "Request Housecall", Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.settings:
                        navigationView.getMenu().findItem(id).setChecked(true);
                        getActivity().getSupportFragmentManager().beginTransaction().replace(R.id.containerFrameLayout, new FragmentRevivSettingsMain()).commit();
                        Toast.makeText(getActivity().getApplicationContext(), "Settings", Toast.LENGTH_SHORT).show();
                        fragment.dismiss();
                        break;
                }
                return true;
            }
        });


        return view;
    }
}

BottomSheetLayout

<?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:id="@+id/bottomsheet_menu"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:alpha="1">

    <android.support.constraint.ConstraintLayout
        android:id="@+id/constraintLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorPrimary"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/txtUsername"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="4dp"
            android:text="User Name"
            android:textAppearance="@style/TextAppearance.AppCompat.Medium"
            android:textColor="@color/label_text_light"
            android:textSize="14sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toEndOf="@+id/imageView4"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.3" />

        <ImageView
            android:id="@+id/imageView4"
            android:layout_width="63dp"
            android:layout_height="65dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@drawable/baseline_face_white_48" />

        <TextView
            android:id="@+id/txtEmail"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:text="Email Address"
            android:textColor="@color/colorText"
            android:textSize="10sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="@+id/txtUsername"
            app:layout_constraintTop_toBottomOf="@+id/txtUsername"
            app:layout_constraintVertical_bias="0.0" />

        <ImageView
            android:id="@+id/imgClose"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:layout_marginBottom="8dp"
            android:layout_marginEnd="16dp"
            android:layout_marginTop="8dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@drawable/baseline_close_white_48dp" />

    </android.support.constraint.ConstraintLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        app:itemTextAppearance="@style/TextAppearance.AppCompat.Body2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/constraintLayout"
        app:itemIconTint="@color/drawer_item"
        app:itemTextColor="@color/drawer_item"
        app:itemBackground="@drawable/menu_background_color"
        app:menu="@menu/bottom_nav_drawer_menu">

        <!-- REMNANTS
        app:itemIconTint="@color/drawer_item"
        app:theme="@style/ThemeOverlay.AppCompat.navTheme"
        app:itemBackground="@drawable/nav_item_drawable"
        app:itemTextColor="@color/drawer_item"
        app:itemBackground="@android:color/transparent"-->

    </android.support.design.widget.NavigationView>

</android.support.constraint.ConstraintLayout>

Relevant sections of the main activity, where the bottom app bar and BottomNav are set up

public class Reviv extends AppCompatActivity implements LocationListener{

    public static String TAG = "Reviv Main";
    private BottomAppBar bottom_app_bar;
    BottomNavigationDrawerFragment fragment;
    private FragmentManager manager = this.getSupportFragmentManager();



    // Functions

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Fabric.with(this, new Crashlytics());
        setContentView(R.layout.activity_reviv);
        uberLayout = findViewById(R.id.uberLayout);
        floatingActionButton = findViewById(R.id.floatingActionButton);
        floatingActionButton.setImageResource(R.drawable.baseline_add_white_24dp);
        final Activity activity = this;
        database = RevivDatabase.getDatabase(this);
        viewModel = ViewModelProviders.of(this).get(RevivViewModel.class);

        // ask for permissions
        displayLocationSettingsRequest(getApplicationContext());
        bringLocationUpdation(this);

        params = defaultParams();


        bottom_app_bar = findViewById(R.id.bottom_app_bar);
        setSupportActionBar(bottom_app_bar);
        fragment = new BottomNavigationDrawerFragment();

        bottom_app_bar.replaceMenu(R.menu.bottomappbar_menu_home);
        bottom_app_bar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem menuItem) {
                switch (menuItem.getItemId()){
                    case R.id.mnu_app_signout:
                        Toast.makeText(getApplicationContext(), "Sign Out", Toast.LENGTH_SHORT).show();
                        break;
                    case android.R.id.home:
                        fragment.show(manager, fragment.getTag());
                        //navigationView.getMenu().getItem(0).setChecked(true);
                        break;

                }
                return true;
            }
        });
        bottom_app_bar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                fragment = new BottomNavigationDrawerFragment();
                fragment.show(getSupportFragmentManager(), fragment.getTag());
            }
        });

        // ask for permissions
        if (ContextCompat.checkSelfPermission(this,
                android.Manifest.permission.INTERNET)
                != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(this,
                    new String[]{android.Manifest.permission.INTERNET},
                    MY_PERMISSIONS_ACCESS_INTERNET);
        }


        if (manager.findFragmentById(R.id.containerFrameLayout) == null) {
            Log.d(TAG, "onCreate: transaction manager state is Empty:  "+ manager.beginTransaction().isEmpty());
            // instantiate fragment and add to view
            Fragment mFragment = new FragmentRevivIncidentDashboard();
            manager.beginTransaction().replace(R.id.containerFrameLayout, mFragment ).commit();
        } else {
            Log.d(TAG, "onCreate: transaction manager state is Empty:  "+ manager.beginTransaction().isEmpty());
        }
    }
}

[UPDATE] - Adding the drawable file's contents as requested by @TheWanderer

Drawable - menu_background_color.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@android:color/transparent"  android:state_checked="false"/>
    <item android:drawable="@color/deeppurple" android:state_checked="true"/>
</selector>
kilokahn
  • 1,136
  • 2
  • 18
  • 38
  • What's in your `menu_background_color` drawable? – TheWanderer Sep 11 '18 at 19:59
  • Hi, thanks for responding. I've added the xml from the drawable to the question. – kilokahn Sep 11 '18 at 20:00
  • Try removing the `android:state_checked="false"`. – TheWanderer Sep 11 '18 at 20:03
  • Hi, I have tried that as well, but left it in place after I saw it in one of the SO Questions. Removing it resulted in no visible change (tried it now). – kilokahn Sep 11 '18 at 20:05
  • 1
    Oh. Swap the order of them. – TheWanderer Sep 11 '18 at 20:10
  • There is some progress in that all the items in the menu get highlighted in the color selected. This is the same as setting the item background to a particular color. However, but what I want is the opposite - only the selected item is to be highlighted. – kilokahn Sep 11 '18 at 20:26
  • No, sorry. I mean, put the second `` above the first one. Just copy the whole line and move it up. – TheWanderer Sep 11 '18 at 20:39
  • In this case, all the items are still highlighted. Could it be that all items are being set Checked? I have also commented out menuItem.setChecked(true) in the code but there is no change. – kilokahn Sep 11 '18 at 20:48
  • selectors will use the first matching item they find for the View in question. It sounds like your items are always checked for some reason. – TheWanderer Sep 11 '18 at 20:50
  • I notice though that while you're calling setChecked(true) you're never calling it with false – TheWanderer Sep 11 '18 at 20:51
  • I agree that something is off. Swapping the colors in the selector items causes all items to fit the color assigned to 'false', implying that none of the items are selected. Commenting out the setChecked or leaving it in seems to make no difference - now I am even more confused! – kilokahn Sep 11 '18 at 20:53
  • if you removed the condition from the item meant for unchecked navigation items, that means it matches any state, which is why it needs to come after the more restrictive item. – TheWanderer Sep 11 '18 at 20:56
  • I agree. However, it seems to have no effect. Manually setting the item to checked in the menu XML works, but selecting a different option still shows the original option as selected. http://tuchangwei.github.io/2016/07/18/The-solution-that-the-menu-item-of-Navigation-View-can-t-change-its-background-When-it-is-selected-checked/ – kilokahn Sep 11 '18 at 21:03
  • Did that link work for you? – TheWanderer Sep 11 '18 at 21:07
  • 1
    Nope, but I figured it out. In my Reviv.class, I kept initializing a new Fragment on each menu button click. Changing the code to if(fragment == null) fragment = new BottomNavigationDrawerFragment(), and setting android:checked="true" on my default item did the trick! – kilokahn Sep 11 '18 at 21:14
  • 1
    You should post that as an answer. – TheWanderer Sep 11 '18 at 21:16
  • 1
    Absolutely! Thank you so much for your assistance. I found your comments very insightful, and learnt a lot from this interaction. :) – kilokahn Sep 11 '18 at 21:18

1 Answers1

0

Thanks to the insightful questioning by @TheWanderer, I finally figured it out.

Firstly, I changed the menu_background.xml to this:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/periwinklegray" android:state_checked="true" />
    <item android:drawable="@color/transparent" android:state_checked="false"  />
</selector> 

From this website, I added a default 'checked' state to my default menu option. However, beyond highlighting (permanently) the first option, there was no real improvement.

I finally figured out that on each menu button click (R.id.home) on the BottomAppBar, a new instance of the Navigation Sheet was being created, and this was easily fixed by changing

bottom_app_bar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                fragment = new BottomNavigationDrawerFragment();
                fragment.show(getSupportFragmentManager(), fragment.getTag());
            }
        });

to this

bottom_app_bar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(fragment == null) fragment = new BottomNavigationDrawerFragment();
                fragment.show(getSupportFragmentManager(), fragment.getTag());
            }
        });
kilokahn
  • 1,136
  • 2
  • 18
  • 38