ViewBinding使用和封装

使用

1、在build.gradle.kts开启视图绑定,用来代替findviewById

android {
...
    viewBinding{
        //开启视图绑定,用来替代findViewById

        enable = true
    }
...
}

2、在Activity中,ActivitySplashBinding 是 View Binding 自动生成,与 activity_splash.xml 布局文件绑定,包含布局中带 id 视图引用。ActivitySplashBinding.inflate(layoutInflater) 加载布局文件并返回 binding 对象,setContentView(binding.root) 将布局的根视图设置为 Activity 的内容视图。

class SplashActivity : BaseActivity() {
     private lateinit var binding:ActivitySplashBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivitySplashBinding.inflate(layoutInflater)
        setContentView(binding.root)
//        setContentView(R.layout.activity_splash)

    }

3、代替findviewbyId

 //  private lateinit var copyrightView:TextView
    override fun initDatum() {
        super.initDatum()
...
        binding.copyright.setText(getString(R.string.copyright,currentYear))
//        val copyrightView = findViewById<TextView>(R.id.copyright)
//        copyrightView.setText(getString(R.string.copyright,currentYear))

    }

封装

1、创建一个BaseViewModelActivity类,使用反射机制动态获取binding,简化使用 View Binding 的 Activity 的创建过程。

open class BaseViewModelActivity<VB : ViewBinding> : BaseLogicActivity() {
    lateinit var binding: VB

    override fun onCreate(savedInstanceState: Bundle?){
        super.onCreate(savedInstanceState)
        //调用inflate方法,创建viewBinding
        binding = ReflectUtil.newViewBinding(layoutInflater,javaClass)

        setContentView(binding.root)
    }
}

2、创建反射类ReflectUtil,在该类中,通过传入的LayoutInflater对象、VB类,首先获取父类的对象(BaseViewModelActivity<ActivitySplashBinding>)。type.actualTypeArguments[0]代表ActivitySplashBinding。然后通过反射传递LayoutInflater对象并得到ActivitySplashBinding中的静态方法inflate。接下来,通过反射调用该方法并返回一个ActivitySplashBinding对象。

object ReflectUtil {
    /**
     * 创建view binding
     */
    fun <VB> newViewBinding(layoutInflater: LayoutInflater, clazz: Class<*>): VB {
        return try {
            //获取泛型参数对象
            val type = try {
                clazz.genericSuperclass as ParameterizedType
            } catch (e: ClassCastException) {
                clazz.superclass.genericSuperclass as ParameterizedType
            }

//type.actualTypeArguments[0]代表BaseViewModelActivity<VB>中的第一个元素ViewBinding,
//被调用是代表具体的VB
            val clazzVB = type.actualTypeArguments[0] as Class<VB>

            //获取inflate方法
//在vb中有public static ActivitySplashBinding inflate(LayoutInflater inflater) {
    // ...
}
            val inflateMethod = clazzVB.getMethod("inflate", LayoutInflater::class.java)
//getMethod的参数是:
//方法名:"inflate",表示要获取的方法是 inflate。
//方法参数类型:LayoutInflater::class.java,表示 inflate 方法的参数是

            inflateMethod.invoke(null, layoutInflater) as VB
//invoke中
//第一个参数:方法所属的对象。如果是静态方法,则传入 null。
//后续参数:方法的实际参数
        } catch (e: Exception) {
            e.printStackTrace()
            throw RuntimeException(e)
        }
    }
}

3、当SplashActivity调用该方法时,可省略更多冗余代码

class SplashActivity : BaseViewModelActivity<ActivitySplashBinding>() {
//    private lateinit var binding:ActivitySplashBinding

//    override fun onCreate(savedInstanceState: Bundle?) {
//        super.onCreate(savedInstanceState)
//        binding = ActivitySplashBinding.inflate(layoutInflater)
//        setContentView(binding.root)
        setContentView(R.layout.activity_splash)
//
//    }


简化成功!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值