我正在将我的应用程序转换为使用一个活动并添加了BottomNavigationView,并努力防止在片段之间导航时重新创建片段,进行不必要的api调用。但是我无法使它工作:
kotlin。TypeCastException: null 不能强制转换为非 null 类型 androidx.navigation.fragment.NavHostFragment at com.example.testapp.NavigationExtensionsKt$setupItemReselected$1.onNavigationItemReselected
活动的布局:
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_container"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/nav_view"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="0dp"
android:layout_marginStart="0dp"
app:menu="@menu/bottom_nav_menu" />
底部导航菜单:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_1"
android:icon="@drawable/ic_1"
android:title="@string/title_1" />
<item
android:id="@+id/homeFragment"
android:icon="@drawable/ic_2"
android:title="@string/home" />
<item
android:id="@+id/navigation_3"
android:icon="@drawable/ic_3"
android:title="@string/title_3" />
</menu>
在主活动中:
class MainActivity : DaggerAppCompatActivity() {
private var currentNavController: LiveData<NavController>? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
nav_view.itemIconTintList = null
if(savedInstanceState == null){
setupBottomNavigationBar()
} // Else, need to wait for onRestoreInstanceState
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
// Now that BottomNavigationBar has restored its instance state
// and its selectedItemId, we can proceed with setting up the
// BottomNavigationBar with Navigation
setupBottomNavigationBar()
}
private fun setupBottomNavigationBar() {
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.nav_view)
val navGraphIds = listOf(R.navigation.mobile_navigation, R.navigation.settings)
val menuItemsIds = listOf(R.id.navigation_1, R.id.homeFragment, R.id.navigation_3)
val defaultIconsIds = listOf(R.drawable.ic_1, R.drawable.ic_2, R.drawable.ic_3)
val selectedIconsIds = listOf(R.drawable.ic_1a, R.drawable.ic_2a, R.drawable.ic_3a)
// Setup the bottom navigation view with a list of navigation graphs (custom extension)
val controller = bottomNavigationView.setupWithNavController(
navGraphIds = navGraphIds,
menuItemsIds = menuItemsIds,
defaultIconsIds = defaultIconsIds,
selectedIconsIds = selectedIconsIds,
fragmentManager = supportFragmentManager,
containerId = R.id.nav_host_container,
intent = intent
)
currentNavController = controller
// updating icons
nav_view.menu.iterator().forEach {
if (it.isChecked) {
it.setIcon(selectedIconsIds[menuItemsIds.indexOf(it.itemId)])
} else {
it.setIcon(defaultIconsIds[menuItemsIds.indexOf(it.itemId)])
}
}
}
override fun onSupportNavigateUp(): Boolean {
return currentNavController?.value?.navigateUp() ?: false
}
}
导航扩展:
//.....
//....
private fun BottomNavigationView.setupItemReselected(
menuItemsIds: List<Int>,
defaultIconsIds: List<Int>,
selectedIconsIds: List<Int>,
graphIdToTagMap: SparseArray<String>,
fragmentManager: FragmentManager) {
setOnNavigationItemReselectedListener { item ->
this.menu.iterator().forEach { it ->
it.setIcon(defaultIconsIds[menuItemsIds.indexOf(it.itemId)])
}
item.setIcon(selectedIconsIds[menuItemsIds.indexOf(item.itemId)])
val newlySelectedItemTag = graphIdToTagMap[item.itemId]
val selectedFragment = fragmentManager.findFragmentByTag(newlySelectedItemTag) as NavHostFragment //TypeCastException happens here
val navController = selectedFragment.navController
// Pop the back stack to the start destination of the current navController graph
navController.popBackStack(
navController.graph.startDestination, false
)
}
}
屏幕为空白,未呈现任何片段视图。
有人能帮我解决这个问题吗?我错过什么了吗?
PS:代码取自可在此处找到的开源应用程序
[编辑]添加导航图:
>
mobile_navigation
<fragment
android:id="@+id/homeFragment"
android:name="com.example.testapp.homeFragment"
android:label="@string/home"
tools:layout="@layout/home_fragment" >
<action
android:id="@+id/homrFragment_to_detailsFragment"
app:launchSingleTop="true"
app:enterAnim="@anim/fragment_open_enter"
app:exitAnim="@anim/fragment_open_exit"
app:destination="@id/detailsFragment" />
</fragment>
<fragment
android:id="@+id/navigation_1"
android:name="com.example.testapp.Fragment_S"
android:label="@string/fragment_s"
tools:layout="@layout/fragment_s" >
<action
android:id="@+id/action_navigation_1_to_detailsFragment"
app:destination="@id/detailsFragment"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_in_left" />
</fragment>
<fragment
android:id="@+id/navigation_3"
android:name="com.example.testapp.Fragment3"
android:label="@string/fragment_ss"
tools:layout="@layout/fragment_ss" />
<dialog
android:id="@+id/detailsFragment"
android:name="com.example.testapp.DetailsFragment"
android:label="InDetails"
tools:layout="@layout/layout_details">
<argument
android:name="arg1"
android:defaultValue=""
app:argType="string"/>
<argument
android:name="arg2"
android:defaultValue=""
app:argType="string" />
</dialog>
导航设置:
<?xml version="1.0" encoding="utf-8"?>
使用导航组件设置 BottomNavigationView 可能有点棘手,但我认为您作为示例遵循的代码有点过度设计,并且/或者用于比初始代码更复杂的目的。
我会在评论中问(没有足够的代表),但是你也能发布导航图吗?一旦你正确设置了导航图、菜单和布局,设置导航控制器就非常容易,但是所有这些都必须一丝不苟地同步,并且这方面的留档并不是很好。
在您回复navgraph之前,我会尝试帮助您解决问题:
首先,改变你的想法
<androidx.fragment.app.FragmentContainerView
自
<fragment
但添加以下标签:
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="@navigation/your_nav_graph.xml"
然后,确保菜单上的 id.xml与所需目的地的相同 ID 匹配,如导航图中所述,例如,您应该有 3 个目的地,称为
android:id="@+id/navigation_1"
android:id="@+id/homeFragment"
android:id="@+id/navigation_3"
您不需要设置任何操作。
之后,只需在具有 BottomNavigationView 的活动中执行此命令:
NavigationUI.setupWithNavController(your_bottom_navigation_view, findNavController(R.id.your_navigation_fragment))
在此之后,导航应该可以正常工作,而无需在“setupBottomNavigationView()”方法或您还发布的导航扩展上设置所有内容。
这样,导航就可以处理所有事情,从背景栈到在BottomNavigationView上突出显示正确的按钮。
我的应用程序有问题。我有一个底部导航视图,包含3个不同的片段,尽管目前只有主要的内容。当我试图从左侧的两个片段中的一个移动到主视图时,问题就出现了,即当底部导航视图被隐藏时。我附上了主代码。 PD:我有25.3.1版本的所有库(如果有用的话)。 感谢您的关注。 activity\u main。xml 主要活动。Java语言 我也给你添加了两张图片。 Ofertas片段 主片段
但是,当我初始化BottomNavigationView时,我会得到: 我正在从一个片段初始化BottomNativigationView。我猜这就是问题所在,但我想不出解决办法。 下面是为片段设置导航的活动的BottomNavigationView xml。
底部导航 (同首页导航,当你没有做到足够好的商品关联时,只要你精心设置好你的网站导航,它就可以让你店铺的各个页面串联起来,方便买家在栏目间快速切换,引导买家前往您期望的页面。) 底部导航主要包括:展示页面(对底部导航的添加及删除)、文字颜色、选中颜色、菜单名称(可自定义)、链接地址(引导买家前往您期望的页面)。
我的天气应用程序上有一个底部导航视图,其中包含3个面板(今天,每小时 以下是问题的说明: 我希望无论单击那些导航视图,数据都保持不变。 我试过使用https://stackoverflow.com/a/60201555/16020235建议但它失败了,只有一个例外: 我发现很难实现他的代码,关于这个问题的其余建议都是用kotlin编写的。 拜托我该怎么解决这件事? 以下是我的代码: my_nav.
这就是我要开始的。所选项目应为主页(中间) 我在OnCreate下有这个 而这个外部Oncreate
本文向大家介绍Flutter实现底部导航,包括了Flutter实现底部导航的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Flutter实现底部导航的具体代码,供大家参考,具体内容如下 BottomNavigationBar使用 底部导航栏 主文件 main.dart (注意导入文件路径) 底部包含三个导航按钮,分别对应三个界面: firstPage.dart secondPage.