Databinding使用篇(迅速上手)
使用前需要在模块级别的build.gradle里面的android闭包里添加:
dataBinding{
enabled = true
}
接着在layout文件中按下Alt + 回车, 将布局转换成data binding layout即可,此时编译就会生成对应的Binding java类
layout文件命名为xxx_xxx.xml生成的java类命名格式为XxxXxxBinding.java
例如:activity_main.xml --> ActivityMainBinding.java
常见使用:
1. 赋值 (variable的种类有很多种,View,基本类型,引用类型等各种各样的)
在xml的 标签下添加标签,写入对应的数据名,以及数据类型
<data>
<variable
name="test"
type="com.dongnaoedu.databinding.Idol" />
<variable
name="eventHandle"
type="com.dongnaoedu.databinding.EventHandleListener" />
<!-- <variable-->
<!-- name="starUtil"-->
<!-- type="com.dongnaoedu.databinding.StarUtils" />-->
<!-- 使用静态类的方法可以直接import然后使用 而不需要在activity里面setXXX-->
<import type="com.dongnaoedu.databinding.StarUtils" />
</data>
variable标签携带的是数据,而import标签则可以引入静态方法
导入数据后就可以使用数据了,在xml中使用 "@{}"的格式去赋值,或者使用工具类`
例如:
<?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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/imageView"
android:layout_width="300dip"
android:layout_height="300dip"
android:src="@drawable/wangzhai"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.495"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.803"
tools:srcCompat="@tools:sample/avatars" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{test.name}"
android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline"
app:layout_constraintVertical_bias="0.176"
tools:text="姓名" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="48dp"
android:text="@{eventHandle.getStar(test.star)}"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView"
tools:text="五星" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="60dp"
android:text="喜欢"
android:onClick="@{()->eventHandle.buttonOnClick()}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<data>
<variable
name="test"
type="com.dongnaoedu.databinding.Idol" />
<variable
name="eventHandle"
type="com.dongnaoedu.databinding.EventHandleListener" />
<!-- <variable-->
<!-- name="starUtil"-->
<!-- type="com.dongnaoedu.databinding.StarUtils" />-->
<!-- 使用静态类的方法可以直接import然后使用 而不需要在activity里面setXXX-->
<import type="com.dongnaoedu.databinding.StarUtils" />
</data>
</layout>
注意,使用variable还需要在java代码中为binding对象传入数据:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
Idol idol = new Idol("旺仔",5);
activityMainBinding.setTest(idol); //为binding设置数据
activityMainBinding.setEventHandle(new EventHandleListener(this));//为binding设置数据
}
}
2. 在xml设置点击回调方法
当回调方法中参数只有一个且为View时:
public class EventHandleListener {
private Context context;
public EventHandleListener(Context context) {
this.context = context;
}
//回调方法,一个参数且为View
public void buttonOnClick(View view){
Toast.makeText(context,"喜欢 ",Toast.LENGTH_SHORT).show();
}
}
使用:xxx类名.xxx方法名
android:onClick="@{eventHandle.buttonOnClick}"
回调方法为其他类型时:
public class EventHandleListener {
private Context context;
public EventHandleListener(Context context) {
this.context = context;
}
//回调方法使用没有带View的参数时
public void buttonOnClick(int data,String name){
Toast.makeText(context,"喜欢 " + data + " "+name,Toast.LENGTH_SHORT).show();
}
}
使用:()->xxx类名.xxx方法名(参数)
xxxxxxxxxx android:onClick="@{()->eventHandle.buttonOnClick(1,test.name)}"
当然也可以写成:
android:onClick="@{(view)->eventHandle.buttonOnClick(1,test.name)}"
只不过此处的view可以忽略不写,但俩种方式都是一样的
因为onclick方法的参数是(View view),所以在回调方法需要传入View对象的时候,我们可以这样子
public class EventHandleListener {
private Context context;
public EventHandleListener(Context context) {
this.context = context;
}
public void buttonOnClick(View view,int data,String name){
Toast.makeText(context,"喜欢 " + data + " "+name,Toast.LENGTH_SHORT).show();
}
}
使用:
android:onClick="@{(theview)->eventHandle.buttonOnClick(theview,1,test.name)}"
上述也是通过lambda表达式将onclick的参数view传入到我们的回调方法中
3. 属性值使用其他view的属性时
例如:
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="48dp"
android:text="@{StarUtils.getStar(test.star)}"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView"
tools:text="五星" />
我要使用上面 id = textView2的text时
<Button
android:id="@+id/button2"
android:text="@{textView2.text}"/>
<!-- button2的text使用了上面id为textView2的text -->
4. 将variable值传入给include包含的子布局时:(前提是variable的type类型一致)
例如:子布局 sub
<data>
<variable
name="sub"
type="com.dongnaoedu.databinding2.Idol" />
</data>
父布局:
<data>
<variable
name="idol"
type="com.dongnaoedu.databinding2.Idol" />
</data>
在父布局中将 idol 传给 子布局的sub
<include
layout="@layout/sub"
app:sub="@{idol}"/>
5. 设置BindingAdapter
例如:为imageview设置图片值
<?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="networkImage"
type="String" />
<variable
name="localImage"
type="int" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/imageView"
app:image="@{networkImage}"
app:defaultImageResource="@{localImage}"
android:layout_width="300dip"
android:layout_height="300dip"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="@tools:sample/avatars" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
写个adapter的java类:
public class ImageViewBindingAdapter {
/**
1.如果重载方法有多个参数的,会优先调用多个参数的
2.优先级:(1)Picasso.get().load(url).placeholder(R.drawable.ic_launcher_background).into(imageView);
* (2)优先级是大于imageView.setImageResource(resId);
* 即 使用(1)加载图片后,再使用(2)也无法改变图片内容
*/
//加载网络图片
@BindingAdapter("image")
public static void setImage(ImageView imageView, String url){
Log.d("ning", "setImage: " + "我是网络图片");
if(!TextUtils.isEmpty(url)){
Picasso.get()
.load(url)
.placeholder(R.drawable.ic_launcher_background)
.into(imageView);
}else{
imageView.setBackgroundColor(Color.GRAY);
}
}
//加载本地图片
@BindingAdapter("defaultImageResource")
public static void setImage(ImageView imageView, int resId){
Log.d("ning", "setImage: " + "我是本地图片");
imageView.setImageResource(resId);
}
// //参数可选,网络图片为空时,加载本地图片
@BindingAdapter(value = {"image", "defaultImageResource"}, requireAll = false)
public static void setImage(ImageView imageView, String url, int resId){
Log.d("ning", "setImage: " + "我是本地+网络图片");
if(!TextUtils.isEmpty(url)){
Picasso.get()
.load(url)
.placeholder(R.drawable.ic_launcher_background)
.into(imageView);
}else{
imageView.setImageResource(resId);
}
}
}
记得给binding类传入值:
public class MainActivity extends AppCompatActivity {
String TAG = "ning";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate: ");
ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
activityMainBinding.setLocalImage(R.drawable.wangzhai);
activityMainBinding.setNetworkImage(networkUrl);
}
}
6.双向绑定-- ObservableField
双向绑定在xml中要区别于赋值,赋值是"@{}", 而双向绑定是"@={}"
用法举例:
存放observableField数据的类:
public class UserViewModel{
public ObservableField<User> userObservableField;
public UserViewModel(){
User user = new User("Jack");
userObservableField = new ObservableField<>();
userObservableField.set(user);
Log.d("TAG", "InitchangeValue: " + userObservableField.get());
}
}
user类:
public class User {
private String userName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public User(String userName) {
this.userName = userName;
}
}
使用:
xml中editText:
<?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="userViewModel"
type="com.dongnaoedu.databinding5.UserViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:text="@={userViewModel.userObservableField.userName}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:onClick="changeValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="chageValue"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/editText" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
注意上面直接是 android:text="@={userViewModel.userObservableField.userName}", 因为默认是调用getUserName()了。
java代码中:
public class MainActivity extends AppCompatActivity {
UserViewModel viewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
viewModel = new UserViewModel();
activityMainBinding.setUserViewModel(viewModel); //为binding设置值
//开启一个定时任务在java代码中改变user的username
new Timer().schedule(new TimerTask() {
@Override
public void run() {
for(int i = 0; i < 3; i++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
User user = (User)viewModel.userObservableField.get();
user.setUserName(String.valueOf(i));
viewModel.userObservableField.notifyChange(); //一定要调用notifyChange()方法通知属性值改变了
}
}
},2000);
}
/**
* button的回调方法,用来测试值是否有双线绑定
* @param view
*/
public void changeValue(View view) {
User user = (User)viewModel.userObservableField.get();
Log.d("TAG", "changeValue: " + viewModel.userObservableField.get() + " " + user.getUserName());
}
}
运行后发现-- 在java代码中改变user的username都会反馈到UI上,在editText中随便输入,都会改变user的username值,做到了数据和UI间的双向绑定。
7 双向绑定BaseObservable的使用
1. 写个类继承BaseObservable,并给所要使用双向绑定的成员变量添加getter和setter方法
2. getter方法要加上@Bindable, 加上后才会生成对应的字段的BR字段
3. 在setter中调用notifyPropertyChanged(BR.xxx) 去通知对应数据改变了
4. 在xml中要用 "@={xxx.xxx}"的形式。
android:text="@={fileViewModel.cacheGenerateSize}"
使用
写类对象,并提供对应的getter和setter方法。 以及为getter方法打上@Bindable注解,setter方法调用notifyPropertyChanged()
public class FileViewModel extends BaseObservable {
private String systemTotalSpace = ""; //系统的总存储空间, MB
@Bindable
public String getSystemTotalSpace() {
return systemTotalSpace;
}
public void setSystemTotalSpace(String systemTotalSpace) {
if(systemTotalSpace != null && !systemTotalSpace.equals(this.systemTotalSpace)){
this.systemTotalSpace = systemTotalSpace;
notifyPropertyChanged(BR.systemTotalSpace);
}
}
在xml中:传入对应值
<data>
<variable
name="fileViewModel"
type="net.sunniwell.fileautobuilder.FileViewModel" />
</data>
<TextView
android:id="@+id/tv_system_total_space"
android:layout_gravity="end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@={fileViewModel.systemTotalSpace}"
android:textColor="#60acfc"
android:textSize="20sp"
android:layout_marginBottom="5dp" />
在java代码中将fileViewModel对象传入给打他binding
fileViewModel.setSystemTotalSpace(" " + Constraint.SYSTEM_TOTAL_SPACE + "MB");
mbind.setFileViewModel(fileViewModel);
java代码中要改变值时,直接调用fileviewmodel.setxxx()即可
8. databinding结合viewmodel以及livedata
结合livedata只需要加上:
activityMainBinding.setLifecycleOwner(this);
使用举例(简单记分牌)
viewmodel:
public class MyViewModel extends ViewModel {
private MutableLiveData<Integer> aTeamScore;
private MutableLiveData<Integer> bTeamScore;
private Integer aLast;
private Integer bLast;
public MutableLiveData<Integer> getaTeamScore() {
if(aTeamScore == null){
aTeamScore = new MutableLiveData<>();
aTeamScore.setValue(0);
}
return aTeamScore;
}
public MutableLiveData<Integer> getbTeamScore() {
if(bTeamScore == null){
bTeamScore = new MutableLiveData<>();
bTeamScore.setValue(0);
}
return bTeamScore;
}
public void aTeamAdd(int i){
saveLastScore();
aTeamScore.setValue(aTeamScore.getValue() + i);
}
public void bTeamAdd(int i){
saveLastScore();
bTeamScore.setValue(bTeamScore.getValue() + i);
}
public void undo(){
aTeamScore.setValue(aLast);
bTeamScore.setValue(bLast);
}
public void reset(){
aTeamScore.setValue(0);
bTeamScore.setValue(0);
}
//记录上一次的分数
private void saveLastScore(){
this.aLast = aTeamScore.getValue();
this.bLast = bTeamScore.getValue();
}
}
layout文件:
<?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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/button1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:background="@android:color/holo_red_light"
android:onClick="@{()->viewModel.aTeamAdd(1)}"
android:shadowColor="@android:color/background_light"
android:text="@string/button1"
android:textColor="#FFFFFF"
app:layout_constraintBottom_toTopOf="@+id/guideline9"
app:layout_constraintEnd_toStartOf="@+id/guideline3"
app:layout_constraintHorizontal_bias="0.423"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline8"
app:layout_constraintVertical_bias="0.564" />
<Button
android:id="@+id/button4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dip"
android:background="@color/colorAccent"
android:onClick="@{()->viewModel.bTeamAdd(1)}"
android:shadowColor="@android:color/background_light"
android:text="@string/button1"
android:textColor="#FFFFFF"
app:layout_constraintBottom_toTopOf="@+id/guideline9"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/guideline3"
app:layout_constraintTop_toTopOf="@+id/guideline8"
app:layout_constraintVertical_bias="0.564" />
<Button
android:id="@+id/button2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:background="@android:color/holo_red_light"
android:onClick="@{()->viewModel.aTeamAdd(2)}"
android:shadowColor="@android:color/background_light"
android:text="@string/button2"
android:textColor="#FFFFFF"
app:layout_constraintBottom_toTopOf="@+id/guideline10"
app:layout_constraintEnd_toStartOf="@+id/guideline3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline9" />
<Button
android:id="@+id/button3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:background="@android:color/holo_red_light"
android:onClick="@{()->viewModel.aTeamAdd(3)}"
android:shadowColor="@android:color/background_light"
android:text="@string/button3"
android:textColor="#FFFFFF"
app:layout_constraintBottom_toTopOf="@+id/guideline11"
app:layout_constraintEnd_toStartOf="@+id/guideline3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline10" />
<Button
android:id="@+id/button6"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:background="@color/colorAccent"
android:onClick="@{()->viewModel.bTeamAdd(3)}"
android:shadowColor="@android:color/background_light"
android:text="@string/button3"
android:textColor="#FFFFFF"
app:layout_constraintBottom_toTopOf="@+id/guideline11"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline3"
app:layout_constraintTop_toTopOf="@+id/guideline10" />
<Button
android:id="@+id/button5"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:background="@color/colorAccent"
android:onClick="@{()->viewModel.bTeamAdd(2)}"
android:shadowColor="@android:color/background_light"
android:text="@string/button2"
android:textColor="#FFFFFF"
app:layout_constraintBottom_toTopOf="@+id/guideline10"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline3"
app:layout_constraintTop_toTopOf="@+id/guideline9" />
<ImageButton
android:id="@+id/imageButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/undoButton"
android:onClick="@{()->viewModel.undo()}"
app:layout_constraintBottom_toTopOf="@+id/guideline12"
app:layout_constraintEnd_toStartOf="@+id/guideline3"
app:layout_constraintHorizontal_bias="0.8"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline11"
app:srcCompat="@drawable/ic_undo_black_24dp" />
<ImageButton
android:id="@+id/imageButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/resetButton"
android:onClick="@{()->viewModel.reset()}"
app:layout_constraintBottom_toTopOf="@+id/guideline12"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.2"
app:layout_constraintStart_toStartOf="@+id/guideline3"
app:layout_constraintTop_toTopOf="@+id/guideline11"
app:srcCompat="@drawable/ic_refresh_black_24dp" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Team A"
android:textSize="@dimen/teamTextSize"
app:layout_constraintBottom_toTopOf="@+id/guideline7"
app:layout_constraintEnd_toStartOf="@+id/guideline3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline2" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Team B"
android:textSize="@dimen/teamTextSize"
app:layout_constraintBottom_toTopOf="@+id/guideline7"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline3"
app:layout_constraintTop_toTopOf="@+id/guideline2" />
<TextView
android:id="@+id/scoreA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf(viewModel.getaTeamScore())}"
android:textColor="@android:color/holo_red_light"
android:textSize="@dimen/scoreTextSize"
app:layout_constraintBottom_toTopOf="@+id/guideline8"
app:layout_constraintEnd_toStartOf="@+id/guideline3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline7"
tools:text="120" />
<TextView
android:id="@+id/scoreB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf(viewModel.getbTeamScore())}"
android:textColor="@color/colorAccent"
android:textSize="@dimen/scoreTextSize"
app:layout_constraintBottom_toTopOf="@+id/guideline8"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline3"
app:layout_constraintTop_toTopOf="@+id/guideline7"
tools:text="100" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.05" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_end="-220dp" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.15" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.35" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.5" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.65" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.8" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.9" />
</androidx.constraintlayout.widget.ConstraintLayout>
<data>
<variable
name="viewModel"
type="com.dongnaoedu.databinding7.MyViewModel" />
</data>
</layout>
使用:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
MyViewModel viewModel = new ViewModelProvider(this, new ViewModelProvider.AndroidViewModelFactory(getApplication())).get(MyViewModel.class);
activityMainBinding.setViewModel(viewModel);
activityMainBinding.setLifecycleOwner(this); //一定要加入这个,否则livedata无效(改变了livedata的值也反馈不到UI上)
}
}