IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> (原创)Jetpack系列(六):DataBinding -> 正文阅读

[移动开发](原创)Jetpack系列(六):DataBinding

什么是DataBinding

DataBinding是Google官方发布的一个框架,是mvvm在android上的一种实现。
主要应用于数据绑定,用于降低布局和逻辑的耦合性,使代码逻辑更加清晰,可以直接绑定数据到xml中,并实现自动刷新。
databinding能够省去findviewbyId,大量减少activity的代码,数据能够单向或双向绑定到layout文件中,有助于防止内存泄漏,而且能自动进行空检测以避免空指针异常

DataBinding的使用

基础配置

首先,在我们build.gradle文件添加对DataBinding的支持
如下图
在这里插入图片描述
然后来到我们需要支持Databinding的xml布局文件中
将光标定位在第一行最开始
然后按下Alt+Enter键
选择Convert to data binding layout
将我们的xml自动转为Databinding的xml
如下图:
在这里插入图片描述
这样,基本的配置就完成了

简单使用

下面我们对一个简单的界面做一个数据的绑定
这个界面只有两个TextView
分别显示姓名和年龄
首先,我们定义一个类

class Person {
    var name = "张三"
    var age = 18
    var address = "北京市朝阳区xxx街道xxx号"
}

然后在支持Databinding的xml里的data标签中,导入这个类

    <data>
        <variable
            name="person"
            type="com.example.databindingdemo.data.Person" />
    </data>

type这里需要用到类的全路径,name代表给这个类取得别名
使用的时候,也很简单
按照以下格式对TextView的文本进行赋值就好了

android:text="@{person.name}"

然后来到我们的MainActivity代码

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val contentView: ActivityMainBinding =
            DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
        val person = Person()
        person.address="修改后地址:上海市xxx街道"
        contentView.person = person
    }
}

注意这边的setContentView使用的是Databinding的,而不是原来的
最后显示界面如下:
在这里插入图片描述
如果要针对int类型
可以做这样一个工具类:

class AgeUtils {
    companion object {
        @JvmStatic
        public fun getAge(age: Int): String {
            return "年龄:$age"
        }
    }
}

然后在data标签里导入

   <import
            type="com.example.databindingdemo.util.AgeUtils"
            />

使用时:

android:text="@{AgeUtils.getAge(person.age)}"

如果要处理Button按钮之类的Onclick方法
也就是事件的处理
也可以先写一个类

class MyOnclickListener(var context: Context) {
    public fun buttonOnclick(view: View) {
        Toast.makeText(context, "触发按钮点击事件", Toast.LENGTH_SHORT).show()
    }
}

然后加上标签

        <variable
            name="myOnclickListener"
            type="com.example.databindingdemo.util.MyOnclickListener" />

使用时:

android:onClick="@{myOnclickListener.buttonOnclick}"

然后在Mainactivity里

contentView.myOnclickListener = MyOnclickListener(this)

这样点击事件就实现了
可以看到
这样做实现了和页面的解耦
Activity里面只需要关注业务即可

二级页面绑定

有时候页面嵌套过多,我们会需要用到二级页面
一般我们会用include标签进行二级页面的嵌套

layout="@layout/sub1"

针对这个sub1的二级xml文件,
如果也需要用到Databinding,
我们也需要用快捷键先转成Databinding的xml格式
如果这个sub1页面也需要用到Person类
也需要在data标签里配置

    <data>
        <variable
            name="person"
            type="com.example.databindingdemo.data.Person" />
    </data>

然后在主页xml里的include标签里需要添加一行属性

app:类的别名="@{类的别名}"

这个类的别名就是variable标签的name属性
代表把对应的类传递到sub1的xml中
比如这样:

app:person="@{person}"

这样配置后,sub1里面才能正常使用Person类中的属性
注意,如果是标签,则不需要进行这样的传递配置
直接在sub1的xml里面配置import标签就好了
最终是这样:

    <data>

        <variable
            name="idol"
            type="com.example.jetpack_databinding.main1.Idol" />

        <import
            type="com.example.jetpack_databinding.main1.StarUtils"/>
    </data>

加载图片

现在来介绍一下如何去用Databinding加载一张图片
首先我们先写好这么一个类

class ImageViewBindingAdapter {
    companion object {
        //加载网络图片
        @BindingAdapter("image")
        @JvmStatic
        fun setImage(imageView: ImageView, url: String) {
            if (!TextUtils.isEmpty(url)) {
                Log.d("ImageViewBindingAdapter", "url:${url}")
            } else {
                Log.d("ImageViewBindingAdapter", "url为空")
            }
        }
    }
}

注意,这和setImage方法上面带了一个@BindingAdapter的注解
我们在注解里写上自己要写的关键字
来到xml,在data标签里自定义一个variable标签
name随便起,type是字段的类型
这里我们要加载网络图片,就设置type为字符串类型,也就是图片的url

<variable
            name="networkImage"
            type="String" />

然后在Imageview里这样配置一个属性

app:image="@{networkImage}"

这里的image就是上面的注解
networkImage就是自定义variable标签的name
最后来到Activity页面

class MainActivity3 : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main3)
        val activityMain3Bind =
            DataBindingUtil.setContentView<ActivityMain3Binding>(this, R.layout.activity_main3)
        activityMain3Bind.networkImage="图片的url"

    }
}

在Activity页面,我们对networkImage进行赋值即可
整个流程,我们注意的就是注解+自定义的variable属性要和Imageview里面的标签对应起来
同样的,如果要加载本地图片
我们也可以自定义一个方法,加上注解,方法参数内传入int类型即可

        //加载本地图片
        @BindingAdapter("image")
        @JvmStatic
        fun setLocalImage(imageView: ImageView, resId: Int) {
            imageView.setImageResource(resId)
        }

最后,如果我们要动态的判断
有网络时加载网络图片,否则加载本地图片,我们可以这样定义我们的方法

        //加载网络图片,没有则加载本地图片
        @BindingAdapter(value = ["image", "defaultImageResource"], requireAll = false)
        @JvmStatic
        fun setImage(imageView: ImageView, url: String?, resId: Int?) {
            if (!TextUtils.isEmpty(url)) {
                Log.d("ImageViewBindingAdapter", "url:${url}")
                Glide.with(imageView.context).load(url).into(imageView)
            } else {
                Log.d("ImageViewBindingAdapter", "url为空2222")
                resId?.let { imageView.setImageResource(it) }
            }
        }

看到这个方法的注解里多了一个requireAll 属性
true代表Imageview里同时定义了image和defaultImageResource时才会进入这个方法
false代表Imageview里只要定义了image和defaultImageResource其中的一个,就会进入这个方法
这也是方便方法的重载
然后我们定义data标签

    <data>
        <variable
            name="networkImage"
            type="String" />

        <variable
            name="localImage"
            type="int" />
    </data>

在Imageview里这样写:

     app:image="@{networkImage}"
     app:defaultImageResource="@{localImage}"

Activity里对两个标签属性进行赋值即可

class MainActivity3 : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main3)
        val activityMain3Bind =
            DataBindingUtil.setContentView<ActivityMain3Binding>(this, R.layout.activity_main3)
        activityMain3Bind.networkImage="图片的url"
        activityMain3Bind.localImage= R.drawable.img1
    }
}

双向绑定

第一种做法

第二种做法

RecyclerView的绑定

DataBinding+ViewModel+LiveData

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-10-12 23:34:18  更:2021-10-12 23:36:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:24:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码