Databinding是谷歌的一个官方支持库,它允许您使用声明性格式而不是通过编程方式将布局中的UI组件绑定到应用程序中的数据源。通常在活动中使用调用UI框架方法的代码来定义布局。例如,调用findViewById()以查找TextView窗口小部件并将其绑定到变量。因为它通过在布局文件中绑定组件,您可以删除活动中的许多UI框架调用,从而使它们更易于维护。这也可以提高应用程序的性能,并有助于防止内存泄漏和空指针异常。
1、布局文件通常只负责UI控件的布局工作,页面中通过代码对控件需要进行各种操作,承担了绝大部分的工作量
2、DataBinding让布局文件承担了部分原本属于页面的工作,也使得布局文件和页面的耦合度进一步降低
3、使得UI控件能够直接合数据模型中的字段绑定,甚至能响应用户的交互。方便实现MVVM
在模块下的build.gradle文件中,启动dataBinding。
android {...dataBinding {enabled = true}
}
显示用户的姓名,年龄和性别,将普通布局文件转换为DataBinding布局文件。
转换后代码如下:
封装用户数据。
package com.sunofbeaches.databindingdemo.domaindata class User(var name: String, var age: Int, var gender: Gender)enum class Gender {FEMALE, MALE
}
拿到布局并给User赋值。
class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)//如何获取到Binding,获取binding后可以给其中的变量赋值val binding:ActivityMainBinding = ActivityMainBinding.inflate(layoutInflater)//获取到Viewbinding.user = User("LiMing", 30, Gender.Male)setContentView(binding.root)}}
(1)DataBindingUtil返回T,T是一个泛型,将其设为ActivityMainBinding,传参activity和Resource.id。
(2)ActivityMainBinding继承ViewDataBinding,返回binding。
(3)不需要设置ContentView,因为已经设置。
代码:
class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)//把布局交给DataBindingUtilval activityMainBinding: ActivityMainBinding =DataBindingUtil.setContentView(this, R.layout.activity_main)//设置数据activityMainBinding.user = User("LiMing", 20, Gender.MALE)}
}
创建一个base包,创建BaseViewFragment类继承Fragmen,创建方法返回View。
abstract class BaseViewFragment : Fragment() {protected var binding: T? = nulloverride fun onCreateView(inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?): View? {binding = DataBindingUtil.inflate(inflater, getSubLayoutId(), container, false)return binding!!.root}abstract fun getSubLayoutId() : Int}
创建BaseVmFragment类。
abstract class BaseVmFragment : BaseViewFragment() {protected lateinit var viewModel: VMoverride fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)//创建ViewModelinitViewModel()//观察数据变化--->更新UIabserverData()//设置相关的事件initEvent()}open fun initEvent(){}open fun abserverData(){}//创建ViewModelprivate fun initViewModel() {viewModel = ViewModelProvider(this).get(getSubVMClass())}abstract fun getSubVMClass(): Class}
class ResourcesActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)val resourcesBinding = DataBindingUtil.setContentView(this,R.layout.activity_resources)resourcesBinding.user = User("LiMing", 20, Gender.MALE)}
}
首先需要修改数据的内容。
修改MainActivity的内容。
class EventActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)val eventBinding =DataBindingUtil.setContentView(this, R.layout.activity_event)eventBinding.textInfo = "点击复制内容"eventBinding.eventHandler = EventHandlers()}
}
方法处理类。
class EventHandlers {fun onFistButtonClick(view: View) {println("第一个按钮点击了...")}fun onTextClickToCopy(text: String) {println("复制的内容是:$text")}
}
方法引用
监听绑定
eventHandler.onTextClickToCopy(textInfo)}"android:text="@{textInfo}" /> eventHandler.completeChanged(cb, isChecked)}"android:text="选择测试" />
布局文件
MainActivity中的代码
package com.example.myapplication;import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.View;import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ObservableField;import com.example.myapplication.databinding.ActivityMainBinding;public class MainActivity extends AppCompatActivity {private ActivityMainBinding activityMainBinding;private DataBean dataBean;@SuppressLint({"SetTextI18n", "InlinedApi"})@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);dataBean = new DataBean(new ObservableField(""));activityMainBinding.setDatabean(dataBean);}
}
DataBean中的代码
package com.example.myapplication;import androidx.databinding.ObservableField;public class DataBean {public final ObservableField data;public DataBean(ObservableField data) {this.data = data;}public ObservableField getData() {return data;}
}
class PlainObjectActivity : AppCompatActivity() {private lateinit var dataBinding: ActivitySimpleObserableBindingoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)dataBinding = DataBindingUtil.setContentView(this,R.layout.activity_simple_obserable)dataBinding.activity = thisdataBinding.simpleUser = SimpleUser().apply {age.set(20)userName.set("Lisa")}}fun onButtonClick() {Toast.makeText(this, "更新数据...", Toast.LENGTH_SHORT).show()dataBinding.simpleUser?.apply {age.set(18)userName.set("LiHua")}}
}
常用的Observable
ObservableBoolean
ObservableByte
ObservableChar
ObservableShort
ObservableInt
ObservableLong
ObservableFloat
ObservableDouble
ObservableParcelable
ObservableArrayMap
ObservableArrayList
override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)dataBinding = DataBindingUtil.setContentView(this,R.layout.activity_simple_obserable)dataBinding.activity = thisdataBinding.observableUser = ObservableObjectUser().apply {age = 20userName = "Lisa"}}fun onButtonClick() {Toast.makeText(this, "更新数据...", Toast.LENGTH_SHORT).show()dataBinding.observableUser?.apply {age = 18userName = "LiHua"}}
}
(1)修饰方法, 要求方法必须public static
(2)方法参数第一个要求必须是View
(3)方法名不作要求
使用方法如下:
@BindingMethods({@BindingMethod(type = android.widget.ProgressBar.class, attribute = "android:indeterminateTint", method = "setIndeterminateTintList"),@BindingMethod(type = android.widget.ProgressBar.class, attribute = "android:progressTint", method = "setProgressTintList"),@BindingMethod(type = android.widget.ProgressBar.class, attribute = "android:secondaryProgressTint", method = "setSecondaryProgressTintList"),
})
public class ProgressBarBindingAdapter {
}
databinding用来实现 vm层和v层的双向绑定关系;取代繁琐的findViewByid();绑定VM层和V层的关联关系,实现双向交互;
作者:李思雨
原文地址:https://blog.csdn.net/m0_54156164/article/details/128105290?spm=1001.2014.3001.5502