首页 > 解决方案 > 与 selectedItem (java) 相关的 Android BottomNavigationView 和 NavController 问题

问题描述

我有一个带有 BottomNavigationView 的 MainActivity,上面有 5 个 menuItem,每个都指向一个片段(主页、帮助、合同、账单、帐户)

在 Home 片段上,有一个指向第 6 个“联系人”片段的链接,该片段不是底部导航栏的项目。目前,当我单击此链接时,它会按预期显示“联系人”片段,但在底部导航栏上,“主页”图标仍然是选中的。我希望改为检查“帐户”图标,因为“联系人”片段属于“帐户”部分(您可以通过帐户>查看联系人访问它)

我使用 navcontroller/navigationUI 进行导航。这是我的 Home_Fragment 的代码:

package com.example.myapp.Fragments;


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

import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProviders;
import androidx.navigation.Navigation;
import androidx.navigation.fragment.NavHostFragment;
import com.example.techcrea.HelpfulTools.UserModel;
import com.example.techcrea.R;

/**
 * A simple {@link Fragment} subclass.
 */
public class Home extends Fragment implements View.OnClickListener {
    //VIEW ATTRIBUTES ##############################################################################
    /**
     * The text that displays our username
     */
    private TextView displayUserName;
    /**
     * The horizontal dividers
     */
    private View divider1, divider2, divider3, divider4, divider5;

    /**
     * The small icons left of each row
     */
    private ImageView iconBills, iconAccount, iconContracts,iconContacts;

    /**
     * The pics for each type of contract
     */
    private ImageView imgFiber, imgPhone, imgOther;

    /**
     * Clickable lines
     */
    private LinearLayout accountRow, billRow, contractsRow, contactsRow, helpBlock;

   //DATA ATTRIBUTES ##############################################################################
    private UserModel user;


    /***
     * Fragment sole constructor
     */
    public Home() {
        // Required empty public constructor
    }



    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

     //Here we set the text that displays the user name
     View view = inflater.inflate(R.layout.fragment_home, container, false);

     loadViewComponents(view);
     user= ViewModelProviders.of(this).get(UserModel.class);
     displayUserName.setText(user.getUser().getValue().getUserName());


     return view;

    }


    /**
     * Binds the design components to variables
     */
    public void loadViewComponents(View view){
        displayUserName = view.findViewById(R.id.txtWelcomeUser);
        divider1 = view.findViewById(R.id.dvd1);
        divider2 = view.findViewById(R.id.dvd2);
        divider3 = view.findViewById(R.id.dvd3);
        divider4 = view.findViewById(R.id.dvd4);
        divider5 = view.findViewById(R.id.dvd5);
        iconBills = view.findViewById(R.id.iconBills);
        iconAccount = view.findViewById(R.id.iconAccount);
        iconContracts = view.findViewById(R.id.iconContracts);
        iconContacts = view.findViewById(R.id.iconContacts);
        imgFiber = view.findViewById(R.id.img_fiber);
        imgPhone = view.findViewById(R.id.img_phone);
        imgOther = view.findViewById(R.id.img_other);
        accountRow = view.findViewById(R.id.row_account);
        billRow = view.findViewById(R.id.row_bills);
        contractsRow = view.findViewById(R.id.row_contracts);
        contactsRow = view.findViewById(R.id.row_contact);
        helpBlock = view.findViewById(R.id.row_help);
        setListeners();
     }


    /**
     * The onClick Listeners for the menu rows.
     */
     public void setListeners(){
        accountRow.setOnClickListener(this);
        billRow.setOnClickListener(this);
        helpBlock.setOnClickListener(this);
        contactsRow.setOnClickListener(this);
        contractsRow.setOnClickListener(this);
    }

    /**
     * this method redirects the user in the belonging section, depending on which row he clicked
     * @param v the source of the click
     */
    @Override
    public void onClick(View v) {

      if (v.equals(accountRow)) {
            NavHostFragment.findNavController(this).navigate(R.id.action_mnuHome_to_mnuAccount);
        } else if (v.equals(billRow)) {
            Navigation.findNavController(v).navigate(R.id.action_mnuHome_to_mnuBills);
        } else if (v.equals(helpBlock)) {
            Navigation.findNavController(v).navigate(R.id.action_mnuHome_to_mnuHelp);
        } else if (v.equals(contactsRow)) {
          Navigation.setViewNavController();
            NavHostFragment.findNavController(this).navigate(R.id.action_global_contactsList);
        } else if (v.equals(contractsRow)) {
            Navigation.findNavController(v).navigate(R.id.action_mnuHome_to_mnuContracts);
        }
    }}

这是我的 mainActivity 布局,其中包含导航栏:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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=".Activities.HomeActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:backgroundTint="@color/toolbar_color"
        app:logo="@drawable/login_logo"
        app:titleMargins="5dp"
        android:paddingStart="10dp"
        android:paddingEnd="10dp" />


    <fragment
        android:id="@+id/fragmentContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/bottom_navigation"
        android:layout_below="@id/toolbar"
        android:layout_marginTop="0dp"
        android:layout_marginBottom="0dp"
        android:scrollbarStyle="insideOverlay"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:navGraph="@navigation/botnavigation"
        app:defaultNavHost="true">
    </fragment>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_navigation"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_alignParentStart="true"
        android:layout_alignParentBottom="true"
        app:itemBackground="@color/navbar_background_color"
        app:itemIconTint="@color/navbar_colors"
        app:itemTextColor="@color/navbar_colors"
        app:menu="@menu/navbar"/>

</RelativeLayout>

这是我的底视图导航栏:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/mnuHome"
        android:icon="@drawable/ic_home_black_24dp"
        android:title="@string/home" />
    <item
        android:id="@+id/mnuHelp"
        android:icon="@drawable/icon_help"
        android:title="@string/help" />
    <item
        android:id="@+id/mnuContracts"
        android:icon="@drawable/icon_contracts"
        android:title="@string/contracts" />
    <item
        android:id="@+id/mnuBills"
        android:icon="@drawable/icon_bill"
        android:title="@string/bills" />
    <item
        android:id="@+id/mnuAccount"
        android:icon="@drawable/icon_account"
        android:title="@string/account" />
</menu>

最后是我的导航图:

<?xml version="1.0" encoding="utf-8"?>
<navigation 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/botnavigation"
    app:startDestination="@id/mnuHome">
    <fragment
        android:id="@+id/mnuHome"
        android:name="com.example.techcrea.Fragments.Home"
        android:label="fragment_home"
        tools:layout="@layout/fragment_home" >
        <action
            android:id="@+id/action_mnuHome_to_mnuContracts"
            app:destination="@id/mnuContracts" />
        <action
            android:id="@+id/action_mnuHome_to_mnuHelp"
            app:destination="@id/mnuHelp" />
        <action
            android:id="@+id/action_mnuHome_to_mnuAccount"
            app:destination="@id/mnuAccount" />
        <action
            android:id="@+id/action_mnuHome_to_mnuBills"
            app:destination="@id/mnuBills" />
    </fragment>
    <fragment
        android:id="@+id/mnuAccount"
        android:name="com.example.techcrea.Fragments.AccountMain"
        android:label="fragment_account_main"
        tools:layout="@layout/fragment_account_main" />
    <fragment
        android:id="@+id/mnuBills"
        android:name="com.example.techcrea.Fragments.BillsMain"
        android:label="fragment_bills_main"
        tools:layout="@layout/fragment_bills_main" />
    <fragment
        android:id="@+id/mnuHelp"
        android:name="com.example.techcrea.Fragments.Help"
        android:label="fragment_help"
        tools:layout="@layout/fragment_help" />
    <fragment
        android:id="@+id/contactsList"
        android:name="com.example.techcrea.Fragments.ContactsList"
        android:label="fragment_account_watchcontacts"
        tools:layout="@layout/fragment_account_watchcontacts" />
    <fragment
        android:id="@+id/mnuContracts"
        android:name="com.example.techcrea.Fragments.ContractsMain"
        android:label="fragment_contracts_main"
        tools:layout="@layout/fragment_contracts_main" /><action android:id="@+id/action_global_contactsList" app:destination="@id/contactsList"/>
</navigation>

还有我声明我的 navcontroller 的 MainActivity :


//Default Android needs

import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.NavigationUI;

import com.example.techcrea.HelpfulTools.UserModel;
import com.example.techcrea.R;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.bottomnavigation.LabelVisibilityMode;

//Fragments
//Android libraries
//Our fragments
//Bottom botnavigation bar
//Toolbar


/**
 * This is the "home" activity and it contains all the fragments we will navigate in.
 * This activity is called by the LoginActivity.
 * @author Caroline
 */
public class HomeActivity extends AppCompatActivity {

    /**
     * Persistent user
     */
    private UserModel user;
    private NavController navController;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //Android default code, do not touch _______________________________________________________
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        //__________________________________________________________________________________________

        //Toolbar instanciation
        Toolbar toolbar = findViewById(R.id.toolbar);
        toolbar.setBackgroundColor(getResources().getColor(R.color.toolbar_color));
        toolbar.setTitle("");
        setSupportActionBar(toolbar);

        //Bottom Navigation : selected item by default at activity launch
        BottomNavigationView bView = findViewById(R.id.bottom_navigation); //Bottom botnavigation bar
        bView.setLabelVisibilityMode(LabelVisibilityMode.LABEL_VISIBILITY_LABELED); //This line is to force the display of texts under nav icons. Otherwise, only the active icon has its label visible.

        //Making it reactive to in-fragment links
        //We add the fragment container layout to our botnavigation controller so it observes botnavigation.
        // To change the way the navController interacts with layout, please see Res>Navigation>Nav_graph.xml
        navController = Navigation.findNavController(this,R.id.fragmentContainer);
        NavigationUI.setupWithNavController(bView, navController);
        NavigationUI.setupActionBarWithNavController(this,navController);

        }
}


如果您看到令人发指的错误,请宽容,我是开发新手,这是我的第一个“专业”工作,我几天前才开始。而且我是法国人,所以我的英语有点烂,但我必须为即将到来的考试写英文评论。在我的实习结束之前,我没有时间完成这个应用程序,所以我尽量让实习生在我之后更清楚地了解它。

非常感谢<3

标签: javaandroidandroid-fragmentsbottomnavigationviewabcustomuinavcontroller

解决方案


推荐阅读