Android车载应用开发与分析(番外)- 2022年Fragment使用解析(上)

本文详细介绍Android Fragment的基础使用方法,包括创建、管理、动画过渡等内容,旨在帮助开发者掌握Fragment的高效运用。

参考资料: https://developer.android.google.cn/guide/fragments?hl=zh_cn
https://zhuanlan.zhihu.com/p/149937029
本文虽然冠名『车载』但涉及到的知识点是所有Android APP开发通用的
本文基于 AndroidX Fragment library 编写,阅读本文需要有一定Fragment使用基础

写这篇博客的原因是最近和同事交流某个项目中遇到的问题时,发现我们对Fragment使用方式相比4-5年前几乎没有进步,遇到问题往往也是想着怎么绕过去而不是分析原因,以至于我们调侃自己为『古法Android的匠人』,所以也就有了这篇博客。2022年的Fragment应该怎么用?

1. Fragment简介

Fragment 表示应用界面中可重复使用的一部分。Fragment 定义和管理自己的布局,具有自己的生命周期,并且可以处理自己的输入事件。Fragment 不能独立存在,而是必须由 Activity 或另一个 Fragment 托管。Fragment 的视图层次结构会成为宿主的视图层次结构的一部分,或附加到宿主的视图层次结构。

实际开发中Fragment也是应用内最重要的组件之一,甚至有人将Fragment视为Android第五大组件。车载应用界面少,我们也几乎都是围绕着Fragment来做HMI的开发。

2. 创建Fragment

在创建Fragment之前需要引入 AndroidX Fragment library。

dependencies {
    def fragment_version = "1.4.1"
    // Java language implementation
    implementation "androidx.fragment:fragment:$fragment_version"
    // Kotlin
    implementation "androidx.fragment:fragment-ktx:$fragment_version"
}

引入library后,创建Fragment通常有以下几个方法

2.1 构造方法

class ExampleKotlinFragment(param1: String, param2: String) : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_example, container, false)
    }
}

// 使用
supportFragmentManager.commit(true) {
    setReorderingAllowed(true)
    add(R.id.container,Example1Fragment("1","2"))
}

使用有参的构造方法来创建Fragment是我们不常用的方式之一,它存在许多缺点。例如:如果Activity发生ConfigChange(屏幕旋转、从主屏分享到副屏),Fragment销毁再重建时会发生异常,导致程序崩溃。

2.2 静态工厂

private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

class ExampleKotlinFragment : Fragment() {

    private var param1: String? = null
    private var param2: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_example, container, false)
    }

    companion object {
        /**
         * 使用此工厂方法,使用提供的参数创建此片段的新实例.
         */
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            ExampleKotlinFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }
}

静态工厂是我们最常用的方式,它的优势在于将传入的参数保存在arguments中,在onCreate时取出使用。这种做法可以覆盖到ConfigChange时的场景,Fragment销毁再重建时所需要的参数依旧可以正常获取。如果使用第一种『构造方法』实例化Fragment,在Fragment被异常销毁后重建时会抛出异常,导致程序崩溃。

2.3 FragmentFactory

使用静态工厂需要我们修改Fragment的实现,所以Android目前建议我们使用FragmentFactory来实例化Fragment。
对于Fragment我们可以选择在构造方法中传入所需要的参数。

class Example1Fragment(val param1: String, val param2: String) : Fragment(R.layout.fragment_example) {

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        Log.e("TAG", "onViewCreated: $param1" )
        // .....
    }

}

然后定义一个Factory集成自FragmentFactory,实现instantiate()然后根据class类型来实例化Fragment。

class ExampleFactory(val param1: String, val param2: String) : FragmentFactory() {

    override fun instantiate(classLoader: ClassLoader, className: String): Fragment =
        when (loadFragmentClass(classLoader, className)) {
            Example1Fragment::class.java -> Example1Fragment(param1, param2)
            else -> super.instantiate(classLoader, className)
        }
}

最后就是使用,需要在Activity的onCreate()方法之前,将自定义的FragmentFactory设定到FragmentManager中。

class MainActivity : AppCompatActivity(R.layout.activity_main) {

    override fun onCreate(savedInstanceState: Bundle?) {
        supportFragmentManager.fragmentFactory = ExampleFactory("1", "2")

        super.onCreate(savedInst
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值