Android DataBinding 笔记三

这篇笔记主要记录常见的应用场景和一些基础知识点

  1. Activity和Fragment之间的交互(它们都有使用DataBinding)
  2. 定义自动生成的绑定类的名称
  3. 和ViewStub的搭配方法
  4. View的ID会在绑定类中自动生成控件的成员变量

Activity视图内包含Fragment和ViewStub

在Activity中包含Fragment和ViewStub是很常见的操作,然而DataBinding可以让他们之间的关联代码减少很多。下面的代码用来演示他们之间通过DataBinding是如何来进行交互的。

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <data>
        <variable
            name="viewStubData"
            type="androidx.databinding.ObservableField&lt;String>" />
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".CustomBindingActivity">
        <fragment
            android:id="@+id/fCustomFragment"
            class="com.im_hero.databinding.CustomBindingFragment"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#2299FF"
            android:text="@{viewStubData}" />
        <ViewStub
            android:id="@+id/viewStub"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout="@layout/custom_view_stub" />
    </LinearLayout>
</layout>

这是Activity的布局文件,其中“<”符号被替换成了“&lt;”,参考表达式语言-常见功能。它包含了一个Fragment和一个ViewStub,其中viewStubData是一个可被观察的数据,用来标识viewStub的显示状态。如下,是对应Activity的代码:

class CustomBindingActivity : AppCompatActivity(), CustomBindingFragment.CustomBindingFragmentListener {
    lateinit var activityCustomBindingBinding: ActivityCustomBindingBinding
    lateinit var fCustomFragment: CustomBindingFragment
    lateinit var tvViewStub: TextView
    lateinit var customViewStubBinding: CustomViewStubBinding
    val oFieldViewStub = ObservableField(INVISIBLE)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        activityCustomBindingBinding = DataBindingUtil.setContentView(this, R.layout.activity_custom_binding)
        activityCustomBindingBinding.viewStubData = oFieldViewStub
        fCustomFragment = supportFragmentManager.findFragmentById(R.id.fCustomFragment) as CustomBindingFragment
    }
    /**
     * [CustomBindingFragment.CustomBindingFragmentListener.showViewStub]用于让CustomBindingFragment控制ViewStub的显示状态
     */
    override fun showViewStub(checked: Boolean) {
        if (::tvViewStub.isInitialized) {
            oFieldViewStub.set(if (checked) VISIBLE else INVISIBLE)
        } else {
            tvViewStub = activityCustomBindingBinding.viewStub.viewStub!!.inflate() as TextView
            // 运行时绑定,因为ViewStub是在运行时并且需要了才会填充到布局内部。
            customViewStubBinding = DataBindingUtil.bind(tvViewStub)!!
            customViewStubBinding.viewStubData = oFieldViewStub
            oFieldViewStub.set(VISIBLE)
        }
    }
}

运行时绑定,比较实用给ViewStub这种在运气期间加入到布局的内部的视图。
有个细节,如下代码中第一个viewStub是activity_custom_binding布局中ViewStub控件的ID在绑定类中生成的属性,其真实类名是androidx.databinding.ViewStubProxy,第二个viewStub才是布局中的ViewStub:

activityCustomBindingBinding.viewStub.viewStub

ViewStub布局文件:

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <import type="android.view.View" />
        <import type="com.im_hero.databinding.ConstantsKt"/>
        <variable
            name="viewStubData"
            type="androidx.databinding.ObservableField&lt;String>" />
    </data>
    <TextView
        android:id="@+id/tvViewStub"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@{`ViewStub:`+viewStubData}"
        android:visibility="@{ConstantsKt.INVISIBLE.equals(viewStubData) ? View.GONE : View.VISIBLE}" />
</layout>

如下是ViewStub的布局文件和常量定义:

// Constants.kt 文件中
const val INVISIBLE = "Invisible"
const val VISIBLE = "Visible""

下面是CustomBindingFragment的布局文件和实现代码:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <data class="CustomDataBinding">
        <import type="com.im_hero.databinding.ConstantsKt"/>
        <variable
            name="showViewStubStatus"
            type="androidx.databinding.ObservableBoolean" />
    </data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".CustomBindingFragment">
        <ToggleButton
            android:id="@+id/btnShowViewStub"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:checked="@{showViewStubStatus}"
            android:textOn="@{ConstantsKt.VISIBLE}"
            android:textOff="@{ConstantsKt.INVISIBLE}" />
    </LinearLayout>
</layout>

其中 <data class=“CustomDataBinding”> 就是用来指定布局自动生成的绑定类名

class CustomBindingFragment : Fragment(), CompoundButton.OnCheckedChangeListener{
    lateinit var customDataBinding: CustomDataBinding
    lateinit var customBindingFragmentListener: CustomBindingFragmentListener
    val oBoolean = ObservableBoolean(false)
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        customDataBinding = CustomDataBinding.inflate(inflater, container, false)
        customDataBinding.showViewStubStatus = oBoolean
        customDataBinding.btnShowViewStub.setOnCheckedChangeListener(this)
        return customDataBinding.root
    }
    override fun onAttach(context: Context) {
        super.onAttach(context)
        if (context is CustomBindingFragmentListener) {
            customBindingFragmentListener = context
        } else {
            throw AndroidRuntimeException("Context must implements CustomBindingFragmentListener")
        }
    }
    override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {
        customBindingFragmentListener.showViewStub(isChecked)
    }
    interface CustomBindingFragmentListener {
        fun showViewStub(checked: Boolean)
    }
}

至此通过Fragment上的按钮控制Activity上的ViewStub的填充和显示隐藏的功能就完成了。这个例子主要是用于演示开头的那几个知识点,特别简单哈,主要是用于演示DataBinding可以给我们减少很多的关联代码。这样我们就主要关注与数据的更新和界面的逻辑,关联代码就完全交给了DataBinding。贴上运行结果图,ViweStub未显示的界面:
启动
显示ViewStub的界面:
结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值