Android 带有Jetpack导航的底部导航菜单不导航
我有一个关于底部导航栏的奇怪问题,虽然我花了大量时间在它上面,但我无法解决。当我以“推荐”的方式(从许多教程中)使用它时,它就是无法导航 那么,我所说的“推荐”方式是什么意思呢:我有一个单独的acticity,其中有一个名为“MainActivity”的navHostFragment。这个主要活动有一个XML布局文件,我将底部导航栏放在其中。BottomNavigationBar还有一个XML布局文件。现在我有了一个名为“FR_Menu”的片段,其中包含一个Java文件和一个XML布局文件。我还有导航图。在片段“FR_Menu”的XML布局中,我没有使用BottomNavigationBar,在Java类中,我没有实例化BottomNavigationBar,因为我已经在主活动中这样做了。但是使用这种方法导航不起作用。尽管底部导航栏正确显示在片段“FR_菜单”中,但当单击底部时,什么也没有发生 现在奇怪的事情来了。当我使用发布的代码,但不将BottomNavigationBar放在主活动的XML布局文件中,而是将其分别放在所有片段的每个XML布局文件中(在本例中为片段“FR_Menu”)时,以及当我还在每个片段的每个Java文件中实例化BottomNavigationBar时(在本例中,片段“FR_菜单”)因此,使用这种方法,我必须在片段的每个XML布局文件中放置BottomNavigationBar,还必须在片段的每个Java文件中实例化BottomNavigationBar。我知道,通常使用Jetpack导航组件时,情况不应该如此,相反,我应该必须在MainActivity中实例化一次,因为BottomNavigationBar只应添加到MainActivity的XML布局文件中 有人知道我尝试实施“推荐”方法时出现了什么问题吗?名称都是正确的(可能在我展示的示例中有一个小错误,因为我必须简化并调整它一点),因为使用第二种方法时(将BottomNavigationBar放在每个XML布局文件和片段的每个Java文件中)导航非常有效(我还尝试了多个项目和目标) 我真的花了很多时间在这件事上,我不知道我犯了什么错误。因此,我非常感谢你的每一个评论,也非常感谢你的帮助 有人知道这种奇怪行为的原因吗 “MainActivity”的Java代码:Android 带有Jetpack导航的底部导航菜单不导航,android,android-fragments,android-jetpack,bottomnavigationview,android-jetpack-navigation,Android,Android Fragments,Android Jetpack,Bottomnavigationview,Android Jetpack Navigation,我有一个关于底部导航栏的奇怪问题,虽然我花了大量时间在它上面,但我无法解决。当我以“推荐”的方式(从许多教程中)使用它时,它就是无法导航 那么,我所说的“推荐”方式是什么意思呢:我有一个单独的acticity,其中有一个名为“MainActivity”的navHostFragment。这个主要活动有一个XML布局文件,我将底部导航栏放在其中。BottomNavigationBar还有一个XML布局文件。现在我有了一个名为“FR_Menu”的片段,其中包含一个Java文件和一个XML布局文件。我还
package com.example.td.bapp;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.NavigationUI;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.td.bapp.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = ActivityMainBinding.inflate(inflater, container, false);
NavController navController = Navigation.findNavController(this, R.id.navHostfragment);
NavigationUI.setupWithNavController(binding.bottomNavigation,navController );
setContentView(binding.getRoot());
return binding.getRoot();
}
}
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
tools:ignore="ExtraText">
<fragment
android:id="@+id/navHostfragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav_graph" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
app:labelVisibilityMode="labeled"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorGreen"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/bottom_navigation"
app:itemIconTint="@color/colorPrimaryDark"
app:itemTextColor="@color/colorAccent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
“MainActivity”的XML布局文件:
package com.example.td.bapp;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.NavigationUI;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.td.bapp.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = ActivityMainBinding.inflate(inflater, container, false);
NavController navController = Navigation.findNavController(this, R.id.navHostfragment);
NavigationUI.setupWithNavController(binding.bottomNavigation,navController );
setContentView(binding.getRoot());
return binding.getRoot();
}
}
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
tools:ignore="ExtraText">
<fragment
android:id="@+id/navHostfragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav_graph" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
app:labelVisibilityMode="labeled"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorGreen"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/bottom_navigation"
app:itemIconTint="@color/colorPrimaryDark"
app:itemTextColor="@color/colorAccent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
这是片段“FR_菜单”的XML布局文件
package com.example.td.bapp;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.NavigationUI;
import com.example.td.bapp.databinding.ActivityMainBinding;
import com.example.td.bapp.databinding.FragmentMenuBinding;
public class FR_Menu extends Fragment implements View.OnClickListener {
// TODO: Rename and change types of parameters
public FR_Menu() {
}
public static FR_Menu newInstance(String param1, String param2) {
FR_Menu fragment = new FR_Menu();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
private FragmentMenuBinding binding;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// return inflater.inflate(R.layout.fragment_menu, container, false);
binding = FragmentMenuBinding.inflate(inflater, container, false);
/*
// IMPORTANT REMARK: When I use the following code in the second option this in the second option,
with the BottomNavigationBar in the XML document, the navigation works well
NavController navController = Navigation.findNavController(getActivity(), R.id.navHostfragment);
NavigationUI.setupWithNavController(binding.bottomNavigation,navController );
*/
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.imageButton_A.setOnClickListener(this);
binding.imageButton_B.setOnClickListener(this);
}
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
@Override
public void onClick(View view) {
if(view.getId() == R.id.imageButton_A) {
String argument = DataBaseEntries.A;
FR_MenuDirections.ActionFRMenuToFRGenericD action =
FR_MenuDirections.actionFRMenuToFRGenericD(argument);
Navigation.findNavController(view).navigate(action);
}
if(view.getId() == R.id.imageButton_B) {
String argument = DataBaseEntries.B;
FR_MenuDirections.ActionFRMenuToFRGenericD action =
FR_MenuDirections.actionFRMenuToFRGenericD(argument);
Navigation.findNavController(view).navigate(action);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar_mainActivity"
android:layout_width="match_parent"
android:layout_height="135dp"
android:background="#435cb53f"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:titleTextColor="@android:color/holo_green_light">
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:gravity="center"
android:layout_gravity="center"
android:textColor="@android:color/white"
android:textSize="24sp"
android:text="Menu" />
</androidx.appcompat.widget.Toolbar>
<ScrollView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="10dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar_mainActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".MainActivity"
tools:ignore="ExtraText">
<ImageButton
android:id="@+id/imageButton_A"
android:layout_width="0dp"
android:layout_height="128dp"
android:background="#00000000"
android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/imageButton_B"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/menu_A" />
<ImageButton
android:id="@+id/imageButton_B"
android:layout_width="0dp"
android:layout_height="128dp"
android:layout_marginTop="12dp"
android:background="#00000000"
android:scaleType="fitCenter"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@id/imageButton_A"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/menu_B" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
导航图的XML代码
<?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/nav_graph"
app:startDestination="@id/FR_LanguageSelection">
<fragment
android:id="@+id/FR_Menu"
android:name="com.example.td.bapp.FR_Menu"
android:label="FR_Menu"
tools:layout="@layout/fragment_menu" >
<action
android:id="@+id/action_FR_Menu_to_FR_LanguageSelection"
app:destination="@id/FR_LanguageSelection" />
</fragment>
<fragment
android:id="@+id/FR_LanguageSelection"
android:name="com.example.td.bapp.FR_LanguageSelection"
android:label="FR_LanguageSelection" >
<action
android:id="@+id/action_FR_LanguageSelection_to_FR_Menu"
app:destination="@id/FR_Menu" />
</fragment>
</navigation>
onCreateView
是一个片段的方法,而不是活动
上的方法,因此框架不会调用main活动
中的方法
事实上,该代码根本不是您在活动中使用的代码
因此,您的main活动
应该如下所示:
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Inflate, and then call setContentView() on the returned view root
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
NavController navController = Navigation.findNavController(this,
R.id.navHostfragment);
NavigationUI.setupWithNavController(binding.bottomNavigation, navController);
}
}
因此,为了确认,您的菜单XML具有
android:id=“@+id/FR\u LanguageSelection”
,但是您的导航图XML在android:id=“@+id/FR\u菜单”中具有完全不同的id
?如果它们不匹配,你希望这两个链接在一起吗?感谢ianhanniballake的评论。我不知道我是否正确理解你的评论。我的FR_菜单XML没有“android:id=“@+id/FR_LanguageSelection”,正如你在我说“菜单XML”时所说的那样",我指的是与底部导航栏关联的菜单XML。啊,好的,是的。我有你发布的内容。但我仍然不明白为什么这是一个问题?正如我在文章中所述,当使用在每个片段的每个XML和Java文件中插入底部导航栏的方法时,导航工作我使用的是单个活动和多个活动片段方法。当我将BottomNavigationBar放在单个活动中时,它只是不导航。但是,当将它放在每个片段(XML和Java文件)中时然后它就可以正确导航了。谢谢你的回答。很遗憾,我的应用程序无法用你建议的代码启动。当我使用你建议的代码时,我在生成应用程序之前收到一条错误消息“无法解析“ActivityMainBinding”中的方法“setContentView”。因此,我将数据绑定行(如您发布的链接中所建议的)替换为“binding=ActivityMainBinding.inflate(getLayoutInflater());”。现在可以构建应用程序,但当我现在启动应用程序时,我立即收到由该行引起的错误“IllegalArgumentException:ID未引用此活动内的视图”“NavController NavController=Navigation.findNavController(this,R.id.navHostfragment);”更新了代码-它是DataBindingUtil.setContentView
。如果只调用inflate()
,而不调用setContentView()
,那么是的,findViewById()
就是findNavController()
dependens-on将失败,因为您从来没有内容视图。感谢ianhanniballake提供进一步的回答。不幸的是,您建议的代码无法生成,因为我收到错误消息“类型参数t具有不兼容的上限:ViewDataBinding和ActivityMainBinding”“我搜索了此错误,并尝试了本文中提到的所有选项:.1.重命名主活动的XML文件。2.清理并重新生成项目3.使缓存无效并重新启动。所有选项均无效。使用建议的代码时错误仍然存在。