这一篇Databinding应该可以帮助迅速上手吧

news/2024/12/20 0:01:42/

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><variablename="test"type="com.dongnaoedu.databinding.Idol" /><variablename="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.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><ImageViewandroid: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" /><TextViewandroid: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="姓名" /><TextViewandroid: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.Guidelineandroid:id="@+id/guideline"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"app:layout_constraintGuide_percent="0.5" /><Buttonandroid: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><variablename="test"type="com.dongnaoedu.databinding.Idol" /><variablename="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 {@Overrideprotected 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;}//回调方法,一个参数且为Viewpublic 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的属性时

例如:

     <TextViewandroid: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时

     <Buttonandroid:id="@+id/button2"android:text="@{textView2.text}"/><!--    button2的text使用了上面id为textView2的text -->

4. 将variable值传入给include包含的子布局时:(前提是variable的type类型一致)

例如:子布局 sub

 <data><variablename="sub"type="com.dongnaoedu.databinding2.Idol" /></data>

父布局:

 <data><variablename="idol"type="com.dongnaoedu.databinding2.Idol" /></data>

在父布局中将 idol 传给 子布局的sub

     <includelayout="@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><variablename="networkImage"type="String" /><variablename="localImage"type="int" /></data><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><ImageViewandroid: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";@Overrideprotected 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><variablename="userViewModel"type="com.dongnaoedu.databinding5.UserViewModel" /></data><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><EditTextandroid: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" /><Buttonandroid: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;@Overrideprotected 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的usernamenew Timer().schedule(new TimerTask() {@Overridepublic 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@Bindablepublic String getSystemTotalSpace() {return systemTotalSpace;}public void setSystemTotalSpace(String systemTotalSpace) {if(systemTotalSpace != null && !systemTotalSpace.equals(this.systemTotalSpace)){this.systemTotalSpace = systemTotalSpace;notifyPropertyChanged(BR.systemTotalSpace);}}
在xml中:传入对应值
    <data><variablename="fileViewModel"type="net.sunniwell.fileautobuilder.FileViewModel" /></data>
                     <TextViewandroid: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.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><Buttonandroid: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" /><Buttonandroid: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" /><Buttonandroid: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" /><Buttonandroid: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" /><Buttonandroid: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" /><Buttonandroid: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" /><ImageButtonandroid: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" /><ImageButtonandroid: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" /><TextViewandroid: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" /><TextViewandroid: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" /><TextViewandroid: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" /><TextViewandroid: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.Guidelineandroid: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.Guidelineandroid: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.Guidelineandroid:id="@+id/guideline4"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical"app:layout_constraintGuide_end="-220dp" /><androidx.constraintlayout.widget.Guidelineandroid: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.Guidelineandroid: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.Guidelineandroid: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.Guidelineandroid: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.Guidelineandroid: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.Guidelineandroid: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><variablename="viewModel"type="com.dongnaoedu.databinding7.MyViewModel" /></data>
</layout>

使用:

public class MainActivity extends AppCompatActivity {@Overrideprotected 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上)}
}

在这里插入图片描述

其他用法:前往官网


http://www.ppmy.cn/news/60004.html

相关文章

JavaScript全解析——本地存储

●就是浏览器给我们提供的可以让我们在浏览器上保存一些数据 ●常用的本地存储 ○ localStorage ○sessionStorage localStorage > 特点: -> 长期存储,除非手动删除否则会一直保存在浏览器中 清除缓存或者卸载浏览器也就没有了 -> 可以跨页面通讯, 也就是说在一个页面…

网络安全:细致分析与防范策略

在当今这个数字化时代&#xff0c;网络已经成为我们生活和工作中不可或缺的一部分。然而&#xff0c;随着网络技术的普及和发展&#xff0c;网络安全问题也日益严峻。本文将详细分析网络安全的相关问题&#xff0c;并提供一些实用的防范策略。 一、什么是网络安全&#xff1f;…

GaussDB数据库基础函数介绍-下

接上一篇&#xff0c;本节继续介绍GaussDB数据库常用基础函数 目录 5、范围函数 6、窗口函数 7、聚集函数 8、安全函数 9、系统信息函数 10、动态脱敏函数 GaussDB常用基础函数介绍与示例 5、范围函数 在GaussDB数据库中&#xff0c;范围函数是指用于处理数据库范围的函…

树莓派启动流程

1) 树莓派上电启动 树莓派上电后&#xff0c;SoC 中的 第一启动程序 首先被执行&#xff0c;其作用是挂载 SD 卡上的 FAT32 分区&#xff0c;从而加载下一阶段的 bootloader。这部分程序被固化在 SoC 的 ROM 中&#xff0c;用户无法进行修改。 4B 在芯片内部增加了一块 EEPRO…

spring-transaction源码分析(2)EnableTransactionManagement注解

概述(Java doc) 该注解开启spring的注解驱动事务管理功能&#xff0c;通常标注在Configuration类上面用于开启命令式事务管理或响应式事务管理。 Configuration EnableTransactionManagement public class AppConfig {Beanpublic FooRepository fooRepository() {// configur…

2023 贵州大数据安全精英赛 --- Crypto childrsa wp

文章目录 题目解题过程解题代码 题目 childrsa.py from Crypto.Util.number import *flag bxxx p getPrime(512) q getPrime(512) n p * q P getPrime(1024) Q getPrime(1024) N P * Q e 65537 gift (PQ) >> 400hint (p & ((1 << 350) - 1)) >&…

抖音小程序|基于天气API实现天气预报功能

文章目录 一、前言包含了功能UI展示 二、开发前的准备三、开发步骤1.app.js 配置2.pages/index.js 演示二维码源码在百度网盘下载 一、前言 参考老版iPhone自带的天气预报APP。目前只有一个界面UI, 后续会更新出更多功能; 包含了功能 - 实况预报 - 未来48小时 - 未来一周的天…

2022 Hubei Provincial Collegiate Programming Contest B. Potion(easy version)

题目链接 Output For each testcase, if Twilight Sparkle couldn’t make the specific mixture, print a single integer: −1. Otherwise, print the minimum number of operation 1 to do that. Example input 3 3 5 1 1 2 6 1 1 5 7 1 1 output 4 3 -1 题目大意 题目保证…