美文网首页
Jetpack学习(二) 数据绑定

Jetpack学习(二) 数据绑定

作者: 飞哥278999401 | 来源:发表于2021-03-31 22:30 被阅读0次

一、配置

在应用的build.gradle里面加上

android {

'''
    dataBinding {
        enabled = true
    }
'''
}

二、布局和绑定表达式

1、建立实体类User

data class User(val firstName: String, val lastName: String)

2、xml布局文件,数据绑定布局文件,以根标记 layout 开头,后跟 data 元素和 view 根元素。

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="user" type="com.example.myapplication.entity.User"/>
    </data>
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.firstName}" />
    </LinearLayout>
</layout>
3、绑定数据
a、activity中使用,ActivityMainBinding是自动生成的,根据基于布局文件的名称,比如布局文件名为 activity_main.xml,因此生成的对应类为 ActivityMainBinding。

如果实在找不到,可以在java(generated)查看


image.png
 val binding: ActivityMainBinding = DataBindingUtil.setContentView(
                this, R.layout.activity_main)
b、如果在fragment、listview、recyclerview中使用,可以使用DataBindingUtil.inflate
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        val fragmentOneBinding = DataBindingUtil.inflate<FragmentOneBinding>(layoutInflater,R.layout.fragment_one,container,false);
        fragmentOneBinding.user = User("zhang","san");
        return fragmentOneBinding.root;
    }



4、表达式语言

算术运算符 + - / * %
字符串连接运算符 +
逻辑运算符 && ||
二元运算符 & | ^
一元运算符 + - ! ~
移位运算符 >> >>> <<
比较运算符 == > < >= <=(请注意,< 需要转义为 <)
instanceof
分组运算符 ()
字面量运算符 - 字符、字符串、数字、null
类型转换
方法调用
字段访问
数组访问 []
三元运算符 ?:

android:text="@{String.valueOf(index + 1)}"
android:visibility="@{age > 13 ? View.GONE : View.VISIBLE}"
android:transitionName='@{"image_" + id}'

5、事件处理

a、方法引用
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="user" type="com.example.myapplication.entity.User"/>
        <variable name="handler" type="com.example.myapplication.fragment.OneFragment"/>
    </data>
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView android:layout_width="wrap_content"
            android:id="@+id/text_tv"
            android:layout_height="wrap_content"
            android:text="@{user.firstName}"
            android:onClick="@{handler.testClick}"
            />
    </LinearLayout>
</layout>
class OneFragment : Fragment() {

    fun testClick(view: View){

       Log.d("hah","hahaha"+view.toString());

    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        val fragmentOneBinding = DataBindingUtil.inflate<FragmentOneBinding>(layoutInflater,R.layout.fragment_one,container,false);
        fragmentOneBinding.user = User("zhang","san");
        fragmentOneBinding.handler = this;
        return fragmentOneBinding.root;
    }

}

注意fragmentOneBinding.handler = this;这一句话不要漏掉

b、监听器绑定

监听器绑定是在事件发生时运行的绑定表达式。它们类似于方法引用,允许运行任意数据绑定表达式。

 fun testClick1(user:User){
        
        Log.d("hah","hahaha"+user);
        
 }

  <TextView android:layout_width="wrap_content"
            android:id="@+id/text_tv"
            android:layout_height="wrap_content"
            android:text="@{user.firstName}"
            android:onClick="@{()->handler.testClick1(user)}"
            />

如果要把点击的view也传递过去,需要

  fun testClick2(view: View,user:User){
        Log.d("hah","hahaha"+user+view.toString());
    }

        <TextView
            android:id="@+id/text_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{(view)->handler.testClick2(view,user)}"
            android:text="@{user.firstName}" />

6、使用可观察的数据对象

可观察性是指一个对象将其数据变化告知其他对象的能力。通过数据绑定库,您可以让对象、字段或集合变为可观察。可观察类有三种不同类型:对象、字段、集合

  • ObservableBoolean
  • ObservableByte
  • ObservableChar
  • ObservableShort
  • ObservableInt
  • ObservableLong
  • ObservableFloat
  • ObservableDouble
  • ObservableParcelable
可观察字段

可观察字段是具有单个字段的自包含可观察对象。原语版本避免在访问操作期间封箱和开箱。如需使用此机制,创建只读属性

    class User {
        val firstName = ObservableField<String>()
        val lastName = ObservableField<String>()
        val age = ObservableInt()
    }

       user.firstName.set("dddd");
       Log.d("haha",user.firstName.get()!!);
可观察集合
     val map = ObservableArrayMap<String, Any>().apply {
        put("firstName", "Google")
        put("lastName", "Inc.")
        put("age", 17)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        val fragmentOneBinding = DataBindingUtil.inflate<FragmentOneBinding>(
            layoutInflater,
            R.layout.fragment_one,
            container,
            false
        );
        fragmentOneBinding.user = map;

        return fragmentOneBinding.root;
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        map.put("firstName","hhhhhhh")
    }

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <import type="androidx.databinding.ObservableMap"/>
        <variable name="user" type="ObservableMap&lt;String, Object>"/>
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:id="@+id/text_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.firstName}" />
    </LinearLayout>
</layout>

不要忘记 fragmentOneBinding.user = map;

c、绑定适配器

可以给一类操作命名直接在xml里面调用

比如,我有Imageview,实际每次都是传入Url加载进控件

在app的gradle里面添加

plugins {
    id 'kotlin-kapt'
}

定义一个object类,例如

object ImageUtil {

    @BindingAdapter("imageurl")
    @JvmStatic
    fun loadImage(view: ImageView, url: String) {
       Glide.with(imageview).load(url).into(imageview)
    }
}

在布局文件里使用

 <ImageView
            android:id="@+id/haha"
            imageurl="@{user.profileUrl}"
            android:layout_width="200dp"
            android:layout_height="200dp" />

@BindingAdapter("imageurl")的imageurl对应布局文件里面控件的imageurl,布局文件传入的字符串会调用到被@BindingAdapter("imageurl")注解的方法。

注意:被@BindingAdapter注解的方法必须为static方法,并且要加@JvmStatic注解,不然会报错,如下

java.lang.IllegalStateException: Required DataBindingComponent is null in class FragmentOneBindingImpl. A BindingAdapter in com.example.myapplication.fragment.ImageUtil is not static and requires an object to use, retrieved from the DataBindingComponent. If you don't use an inflation method taking a DataBindingComponent, use DataBindingUtil.setDefaultComponent or make all BindingAdapter methods static.

相关文章

网友评论

      本文标题:Jetpack学习(二) 数据绑定

      本文链接:https://www.haomeiwen.com/subject/qeqnhltx.html