MVVM之DataBinding布局使用自定义View

某日,我打算用databinding写一个布局,体验一下MVVM的快乐,于是,发生了接下来的故事。
我要实现的大概是这么一个布局:
在这里插入图片描述
于是,我首先写了这么一个自定义的组合控件

class SpecialText : ConstraintLayout {
    constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
        context, attrs, defStyleAttr
    ) {
        initView(context, attrs)
    }

    private fun initView(context: Context, attrs: AttributeSet) {
        LayoutInflater.from(context).inflate(R.layout.view_special_text, this, true)
        val mTypeArray =
            context.obtainStyledAttributes(attrs, R.styleable.SpecialText)

        val text0 = mTypeArray.getString(R.styleable.SpecialText_showTexta)
        val text1 = mTypeArray.getString(R.styleable.SpecialText_showTextb)

        mTypeArray.recycle()

        if (text0 != null) {
            specialText0.text = text0
        }
        if (text1 != null) {  
            specialText1.text = text1
        }

    }
}

非常简单的标题以及描述内容,接着,写databinding布局:

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>

        <variable
            name="viewModel"
            type="com.hyt.cupcake.view.activity.developer.DeveloperViewModel" />

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".view.activity.developer.DeveloperActivity">

        <com.july.viewlibrary.customView.viewGroup.SimpleTitle
            android:id="@+id/developerTitle0"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:titleName="开发者设置" />

        <com.hyt.SpecialText
            android:id="@+id/developerText0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:layout_marginTop="12dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/developerTitle0"
            app:showTexta="厂商品牌" />

        <com.hyt.SpecialText
            android:id="@+id/developerText1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="12dp"
            app:layout_constraintStart_toStartOf="@+id/developerText0"
            app:layout_constraintTop_toBottomOf="@+id/developerText0"
            app:showTexta="设备型号"
            app:showTextb="@{viewModel.brand}" />


    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

一切似乎都很美好,activity里的代码就只是这些:

class DeveloperActivity : BaseActivity() {

    private lateinit var databinding : ActivityDeveloperBinding
    private val viewModel by viewModels<DeveloperViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        databinding = DataBindingUtil.setContentView(this,R.layout.activity_developer)
        initView()

    }

    private fun initView() {
        databinding.viewModel = viewModel
        
       }
    }

把布局换成databinding,并把viewModel设置进去
这个是我的ViewModel:

class DeveloperViewModel: ViewModel() {

    val brand = MutableLiveData(Build.BRAND)  //厂商品牌
    val device = MutableLiveData(Build.DEVICE)  //设备型号
    val flavor = MutableLiveData(BuildConfig.FLAVOR)   //渠道
    val imei = MutableLiveData(Common.getIMEI())   //imei
    val model = MutableLiveData(Build.MODEL)   //手机型号
   // val oaid = MutableLiveData(Build.MODEL)   //oaid
    val system = MutableLiveData("安卓 ${Build.VERSION.RELEASE}")   //系统版本

   
}

ok,点击运行,哦吼,怎么会这样

在这里插入图片描述

这问题其实之前就遇到过,不过当时项目紧急,就直接使用了其他的方案,检查了一下代码,之后,我写了一个TextView,并把使用ViewModel的自定义View注释掉

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data>

        <variable
            name="viewModel"
            type="com.hyt.cupcake.view.activity.developer.DeveloperViewModel" />

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".view.activity.developer.DeveloperActivity">

        <com.july.viewlibrary.customView.viewGroup.SimpleTitle
            android:id="@+id/developerTitle0"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:titleName="开发者设置" />

        <com.hyt.SpecialText
            android:id="@+id/developerText0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:layout_marginTop="12dp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/developerTitle0"
            app:showTexta="厂商品牌" />

       <!-- <com.hyt.SpecialText
            android:id="@+id/developerText1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="12dp"
            app:layout_constraintStart_toStartOf="@+id/developerText0"
            app:layout_constraintTop_toBottomOf="@+id/developerText0"
            app:showTexta="设备型号"
            app:showTextb="@{viewModel.brand}" />-->

        <TextView
            android:layout_marginTop="12dp"
            app:layout_constraintStart_toStartOf="@+id/developerText0"
            app:layout_constraintTop_toBottomOf="@+id/developerText0"
            android:text="@{viewModel.brand}"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>


    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

运行:在这里插入图片描述
妙啊,TextView竟然可以正常使用viewmodel的值,接下来(一顿搜索…databinding找不到bindingImpl类,databinding与自定义控件…)
我又尝试了把项目的主build文件,所有模块的build都删掉,Clean Project之后Rebuild Project,但都无济于事,包括类名可能出现的问题,以及include布局时,要引用变量,但如果这么做多次使用布局就没法了。
难道,快乐就到此为止了吗!
那肯定是不可以的,
我首先看了看布局,发现自定义的控件是的属性是app开头的,而TextView的text属性,是android开头的,难道,app开头的属性就是不配吗,我们天生就低人一等吗?啊不是吧啊sir!
不服输的我接下来找到了ActivityDeveloperBindingImpl这个类,找到了给TextView使用viewmodel的值的地方

在这里插入图片描述
嗯~妙哉,接着一顿思考,然后灵光一现,接着我给自定义控件加了这么两个set方法

package com.hyt

import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.constraintlayout.widget.ConstraintLayout
import kotlinx.android.synthetic.main.view_special_text.view.*


/**
 * author : Hyt
 * time : 2020/09/14
 * version : 1.0
 * 显示对应文本和信息
 * 格式:
 * 姓名   阿水
 */
class SpecialText : ConstraintLayout {
    constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
        context, attrs, defStyleAttr
    ) {
        initView(context, attrs)
    }

    private fun initView(context: Context, attrs: AttributeSet) {
        LayoutInflater.from(context).inflate(R.layout.view_special_text, this, true)
        val mTypeArray =
            context.obtainStyledAttributes(attrs, R.styleable.SpecialText)

        val text0 = mTypeArray.getString(R.styleable.SpecialText_showTexta)
        val text1 = mTypeArray.getString(R.styleable.SpecialText_showTextb)

        mTypeArray.recycle()

        if (text0 != null) {
            specialText0.text = text0
        }
        if (text1 != null) {
            specialText1.text = text1
        }

    }

    fun setShowTexta(str: String){
        specialText0.text = str
    }

    fun setShowTextb(str: String){
        specialText1.text = str
    }

}

在这里插入图片描述
可以了,只要添加属性的set方法就ok了,嗯,真好,又可以继续快乐下去了

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值