Jayce
Jayce

Reputation: 842

Android Bottom Navigation

I have been implementing a bottom navigation bar into my app, the problem is no matter which activity I am on the dashboard icon is the highlighted one. How do I get it so whichever activity I am on is the highlighted one?

public class Dashboard extends AppCompatActivity
    implements View.OnClickListener
{

private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
        = new BottomNavigationView.OnNavigationItemSelectedListener()
{
    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item)
    {
        switch (item.getItemId())
        {
            case R.id.navigation_request:
                Intent r = new Intent(Dashboard.this, Request.class);
                startActivity(r);
                finish();
                break;
            case R.id.navigation_settings:
                Intent s = new Intent(Dashboard.this, AppSettings.class);
                startActivity(s);
                finish();
                break;
        }
        return false;
    }
};

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_dashboard);

BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
    navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
}

Here is my XML Menu file

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
    android:id="@+id/navigation_home"
    android:icon="@drawable/ic_home_black_24dp"
    android:title="@string/title_home" />

<item
    android:id="@+id/navigation_request"
    android:icon="@drawable/ic_request_icon"
    android:title="@string/title_request" />

<item
    android:id="@+id/navigation_settings"
    android:icon="@drawable/ic_icon_settings"
    android:title="@string/title_settings" />

</menu>

Here is how I use the navigation in my activity_dashboard

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<FrameLayout
    android:id="@+id/content"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1">

<!-- ONLY TEXTVIEWS ARE HERE -->

</FrameLayout>



<android.support.design.widget.BottomNavigationView
    android:id="@+id/navigation"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:background="?android:attr/windowBackground"
    app:menu="@menu/navigation" />

</LinearLayout>

Upvotes: 0

Views: 3540

Answers (3)

Ankita Bhatt
Ankita Bhatt

Reputation: 21

Step - 1 put below code into app level Build.gradle

implementation 'androidx.navigation:navigation-fragment:2.3.0'

implementation 'com.google.android.material:material:1.2.1'

implementation 'androidx.navigation:navigation-ui:2.3.0'

Step - 2 put below code into activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="?attr/actionBarSize">

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="0dp"
        android:layout_marginEnd="0dp"
        android:background="?android:attr/windowBackground"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/bottom_nav_menu" />

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toTopOf="@id/nav_view"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Step - 3 put below code into menu/bottom_nav_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/navigation_home"
        android:icon="@drawable/ic_home_black_24dp"
        android:title="@string/title_home" />
    <item
        android:id="@+id/navigation_dashboard"
        android:icon="@drawable/ic_dashboard_black_24dp"
        android:title="Orders" />
    <item
        android:id="@+id/navigation_notifications"
        android:icon="@drawable/ic_notifications_black_24dp"
        android:title="Services" />
    <item
        android:id="@+id/navigation_account"
        android:icon="@drawable/ic_notifications_black_24dp"
        android:title="Account" />
</menu>

Step - 4 put below code into MainActivity.java

import android.os.Bundle;
import android.view.MenuItem;

import com.example.bottomnavigationdemo.ui.account.AccountFragment;
import com.example.bottomnavigationdemo.ui.dashboard.DashboardFragment;
import com.example.bottomnavigationdemo.ui.home.HomeFragment;
import com.example.bottomnavigationdemo.ui.notifications.NotificationsFragment;
import com.google.android.material.bottomnavigation.BottomNavigationView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        BottomNavigationView navView = findViewById(R.id.nav_view);
        navView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                switch (item.getItemId()) {
                    case R.id.navigation_home:
                        Fragment fragment = new HomeFragment();
                        getSupportFragmentManager().beginTransaction()
                                .replace(R.id.nav_host_fragment, fragment, fragment.getClass().getSimpleName())
                                .commit();
                        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
                        transaction.replace(R.id.nav_host_fragment, fragment, fragment.getClass().getSimpleName());
                        transaction.commit();
                        return true;

                    case R.id.navigation_dashboard:
                        Fragment fragment2 = new DashboardFragment();
                        transaction = getSupportFragmentManager().beginTransaction();
                        transaction.replace(R.id.nav_host_fragment, fragment2, fragment2.getClass().getSimpleName());

                        transaction.commit();
                        return true;

                    case R.id.navigation_notifications:
                        Fragment fragment3 = new NotificationsFragment();
                        transaction = getSupportFragmentManager().beginTransaction();
                        transaction.replace(R.id.nav_host_fragment, fragment3, fragment3.getClass().getSimpleName());
                        transaction.commit();
                        return true;

                    case R.id.navigation_account:
                        Fragment fragment4 = new AccountFragment();
                        transaction = getSupportFragmentManager().beginTransaction();
                        transaction.replace(R.id.nav_host_fragment, fragment4, fragment4.getClass().getSimpleName());
                        transaction.commit();
                        return true;
                }
                return true;
            }

        });
    }

}

Step - 5 put below code into HomeFragment.java

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;

import com.example.bottomnavigationdemo.R;
import com.example.bottomnavigationdemo.ui.dashboard.DashboardFragment;

public class HomeFragment extends Fragment {

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_home, container, false);
        return root;
    }
}

Upvotes: 1

Ben P.
Ben P.

Reputation: 54194

Using many different Activity instances that all duplicate the BottomNavigationView and its associated code (like the OnNavigationItemSelectedListener etc) is not recommended. Instead, you would generally use a single Activity that hosts the BottomNavigationView as well as multiple Fragment instances that are .replace()d into your content area as the user interacts with the BottomNavigationView.

That being said, let's see if we can solve your problem.

There are two pieces to this puzzle. The first is simple: you have to indicate which item in your BottomNavigationView should be selected. This can be achieved by calling setSelectedItemId(). Add something like this to your onCreate() method.

    navigation.setSelectedItemId(R.id.navigation_settings);

The second is a little more complicated. When you call setSelectedItemId(), the system is going to behave as though a user had tapped on that item. In other words, your OnNavigationItemSelectedListener will be triggered.

Looking at your posted listener, I notice that you always return false. If you check the documentation for onNavigationItemSelected(), you will find

Returns: true to display the item as the selected item and false if the item should not be selected

So the call to setSelectedItemId() won't work without also changing your listener to return true.

You could still solve the problem with just a setSelectedItemId() call if you place that call before your setOnNavigationItemSelectedListener() call, but that's just masking the problem. It'd be better to fix your listener to return true in cases where you want the tapped item to appear as selected.

Upvotes: 1

Ratul Bin Tazul
Ratul Bin Tazul

Reputation: 2151

Just use method setSelectedItemId(int id) which let's you mark an item as selected as if it was tapped.

Like this:

BottomNavigationView bottomNavigationView;
bottomNavigationView = (BottomNavigationView) 
findViewById(R.id.bottomNavigationView);
bottomNavigationView.setSelectedItemId(R.id.my_menu_item_id);

Upvotes: 0

Related Questions