简介
使用的技术是观察者与被观察者的模式,在google推荐的案例中也有使用到,现在我把它封装成一个扩展函数,使得使用更加简单明了
注意
1、在build.gradle添加databinding,在android{}节点添加
dataBinding {
enabled true
}
或者(一般用下面的) :
buildFeatures {
dataBinding = true
viewBinding true
}
2、在activity里绑定binding
在fragment里绑定binding: _binding = FragmentReturnMainBinding.inflate(inflater, container, false)
1、TextView显示的值随activity的属性值改变同时改变–LiveData
代码
MainActivity
class MainActivity : AppCompatActivity() {
private val mutableLiveData = MutableLiveData<String>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
tv2.bindValue(mutableLiveData,this)
bt1.setOnClickListener {
mutableLiveData.value="我爱李曼娜"
}
}
fun TextView.bindValue( mutableLiveData:MutableLiveData<String>,lifecycleOwner:LifecycleOwner){
var text1: LiveData<String> = Transformations.map(mutableLiveData) {
it
}
text1.observe(lifecycleOwner, Observer<String> {
this.text = it
})
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<Button
android:id="@+id/bt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="赋值3"/>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
2、xml使用layout–data方式双向绑定
功能:点击按钮按钮换背景颜色,字体换颜色,textview换内容,效果图:
代码:
public class User {
private String status;
private String hint;
private boolean isOnline;
public User(String status, String hint, boolean isOnline) {
this.status = status;
this.hint = hint;
this.isOnline = isOnline;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getHint() {
return hint;
}
public void setHint(String hint) {
this.hint = hint;
}
public boolean getIsOnline() {
return isOnline;
}
public void setIsOnline(boolean isOnline) {
this.isOnline = isOnline;
}
}
MainActivity :
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import android.os.Bundle;
import android.view.View;
import com.example.databinding.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
User user = new User("已下线", "快开启一天的旅程吧!!", false);
binding.setUser(user);
}
public void switchStatus(View view) {
User user = new User("已上线", "祝您旅途愉快,谢谢!!", true);
binding.setUser(user);
}
}
<?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="user"
type="com.example.databinding.User" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/tvStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.status}"
app:layout_constraintBottom_toTopOf="@+id/tvHint"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tvHint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.hint}"
app:layout_constraintBottom_toTopOf="@+id/button"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvStatus" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@{user.isOnline?@drawable/btn_shape:@drawable/btn_shape_press}"
android:onClick="switchStatus"
android:text="状态切换"
android:textColor="@{user.isOnline?@color/purple_200:@color/teal_200}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tvHint" />
<!-- android:background="@{user.isOnline?@color/purple_200:@color/teal_200}"-->
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
btn_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="10dp" />
<solid android:color="#2196F3" />
</shape>
btn_shape_press.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="10dp" />
<solid android:color="#FF018786" />
</shape>
主题:<style name="Theme.Databinding" parent="Theme.MaterialComponents.DayNight.NoActionBar.Bridge">
下载地址:https://download.csdn.net/download/wy313622821/33937925
注意:
1.ActivityMainBinding 这里的命名需要与xml的名称对应
3、MVVM双向绑定(过滤器)
<?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.abtalk.databinding.MainViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.age+`:字符串:`}"
android:visibility="@{viewModel.visibility}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!--android:visibility="@{viewModel.visibility}" 这里比较复杂的逻辑运算放到mainactivity代码里写-->
<TextView
android:id="@+id/tv11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{(viewModel.age>13)?@string/cnr:@string/w_cnr}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="change"
android:text="改变"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
activity代码
class MainActivity : AppCompatActivity() {
private lateinit var mainViewModel: MainViewModel
private lateinit var databindng: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
databindng = DataBindingUtil.setContentView(this, R.layout.activity_main)
mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
databindng.viewModel = mainViewModel
}
fun change(view: View) {
mainViewModel.age.set(15)
}
}
MainViewModel
class MainViewModel : ViewModel() {
val age = ObservableInt(1)
val visibility = object : ObservableInt(age) {
override fun get(): Int {
Log.e("wang", "===>")
return if (age.get() > 13)
View.GONE
else
View.VISIBLE
}
}
}
注意:上面的visibility如果没有在xml里面绑定的话,是不会触发输出的(Log.e(“wang”, “===>”))
String.xml
<resources>
<string name="app_name">Databinding</string>
<string name="cnr">成年人</string>
<string name="w_cnr">未成年人</string>
</resources>
完整的代码地址:https://download.csdn.net/download/wy313622821/86905039
4、dataBinding中TextView中字符串的拼接处理
第一种:
android:text="@{ `字符串:` + str}"/>
第二种:
android:text=‘@{@string/user_name+bean.name}’
这里的引号需要使用单引号
5、监听某个值的改变,并做一些其他的操作
某个值为:
var aa: ObservableField = ObservableField(0)
监听:
aa.addOnPropertyChangedCallback(object : OnPropertyChangedCallback() {
override fun onPropertyChanged(observable: Observable?, i: Int) {
Log.e("wang","===>"+i)
}
})
让这个值改变
aa.set(10)
这样就会触发上面的回调接口
6、绑定点击事件
第一步,activity中把xml里的viewmodel跟activity的viewmodel实例进行绑定
private val returnListViewModel by viewModels<ReturnListViewModel>()
binding.viewModel = returnListViewModel
<variable
name="viewModel"
type="***.medicine.module_return.returned.viewmodel.ReturnListViewModel" />
第二步,带参数的点击:@{() -> viewModel.click(1)}
android:onClick="@{() -> viewModel.click(1)}"
public void click(num:Int){
}
课外知识:可以把xml里的frag跟activity的this实例进行绑定,把绑定点击事件放在fragment里
<variable
name="frag"
type="***.medicine.module_return.returned.viewmodel.Fragment" />
binding.frag = this
双向绑定的显示隐藏需要用到View:
就可以使用View.Gone
7、高级用法
android:text='@{username??"null"}'
如果表达式username为null时,则显示“null”, 不为空显示username的值
<data>
<!--使用Java某些类都要通过import导入才能正常使用-->
<import type="android.text.TextUtils" alias="textUtlis" />
</data>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/bt_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:enabled="@{!textUtlis.isEmpty(username)?!textUtlis.isEmpty(password)?true:false:false}"
android:onClick='@{v->loginModel.login(username ?? "",password ?? "",v) }'
android:text="登陆" />
使用 && 进行多条件判断
我们都希望可以在databinding layout表达式中直接使用&& 逻辑判断,但遗憾会报错!这里可以使用&的转义字符 & 替代,则上面的用户名密码判空操作可以直接写成
android:enabled="@{!TextUtlis.isEmpty(username) & & !TextUtlis.isEmpty(password)}"
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)