Compose很好用,可是在真实使用到项目时,咱们还需求处理一些问题。

我要开发一个这样的页面,外层用Bottom Navigation Activity,每个tab对应的一个fragment,页面内容我用Compose来填充,不运用xml来布局,因为Compose太好用了,如果不是页面缓存的原因,我可能会选择全部运用Compose来写。

我曾尝试运用material3的Navigation Bar来处理tab,可是每次点击tab后,页面总会从头加载,虽然功能实现了,可是这不是我想要的成果,我期望从头点回页面时,页面的方位、状态仍是之前的样子。

这是终究的作用

Compose + Fragment是一个不错的选择

创立 Bottom Navigation Activity

New Project时,选择Bottom Navigation Activity,体系就会帮你创立一个带有3个tab页面的使用,此刻都是正常的,可是我的使用需求有4个tab,当我将第4个tab加上去之后,我发现tab item,只要选中的,才会展现文字标题,就像下面这个样子。

Compose + Fragment是一个不错的选择

那为什么会这样呢,其实是因为Android有意而为之,关于Bottom Navigation Item的设计规范,能够参考这儿Bottom Navigation,那要怎么样,才能让所有的tab item都能够展现文字标题呢,只需求在onCreate中设置下显现形式即可

val navView: BottomNavigationView = binding.navView
navView.labelVisibilityMode = NavigationBarView.LABEL_VISIBILITY_LABELED

添加 Compose 到 fragment 里

现在的代码,又臭又长,让咱们先把Frament对应的xml布局文件删掉,不需求在xml中写布局了,另外把Fragment中onCreateView也整理一下,填充上简洁的代码片段,如下

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
    return ComposeView(requireContext()).apply {
        setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
        setContent {
            Text("HomeFragment")
        }
    }
}

瞬间整个国际都清净了,值得一提的是,ComposeView是普通视图和Compose视图的桥梁,起着至关重要的作用。

添加这段代码后,会报错,因为没有添加对应Compose库,等候Android Studio主动补全需求的库文件,补全之后,错误会消失,而且会在build.gradle添加好依赖。

这个时分运行项目,咱们发现一个古怪的问题,页面顶部会出现一部分空白,有一块白色区域

Compose + Fragment是一个不错的选择

咱们需求找到activity_main.xml文件,删去其间的这行代码,这个高度为56dp的空白就能够消失了。

android:paddingTop="?attr/actionBarSize"

填充列表页面

不得不说Compose实在比xml布局好用多了,写起来更像是写SwiftUI和Flutter。列表页面填充完之后,我发现列表最后一项,并不能彻底展现,被Bottom Nav View给挡住了

Compose + Fragment是一个不错的选择

怎么处理呢,咱们仍是需求找到activity_main.xml文件,将fragment的高度,由match_parent改为默许0dp,不要过早的撑满容器,这样页面就能够显现正常了

android:layout_height="0dp"

替换布局文件中的fragment

处理掉上面的那么些问题之后,这儿还有一个黄色的小提示,Android Studio主张咱们把fragment替换成FragmentContainerView,当咱们根据主张点击替换后,再运行项目,咱们发现使用崩溃了

Caused by: java.lang.IllegalStateException: Activity xx.xx.xx.MainActivity@7b7a278 does not have a NavController set on 2131231026

此刻咱们需求找到MainActivity,将其间的一行代码

val navController = findNavController(R.id.nav_host_fragment_activity_main)

替换为

val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment_activity_main) as NavHostFragment
val navController = navHostFragment.navController

此刻就一切都正常了,能够进行下一步了。

参考链接

stackoverflow.com/questions/5…
developer.android.com/jetpack/com…
stackoverflow.com/questions/5…
blog.csdn.net/Misdirectio…