这一篇Databinding应该可以帮助迅速上手吧
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上)}
}
其他用法:前往官网
相关文章:
这一篇Databinding应该可以帮助迅速上手吧
Databinding使用篇(迅速上手) 使用前需要在模块级别的build.gradle里面的android闭包里添加: dataBinding{enabled true}接着在layout文件中按下Alt 回车, 将布局转换成data binding layout即可,此时编译就会生成对…...
【PHP在线定制商城网站源码V3.0】开源的DIY在线定制商城系统+在线礼品定制
源码下载:https://download.csdn.net/download/m0_66047725/87637177 PHP在线定制商城网站源码,免费开源、免费下载。本商城基于mycncart开发。安装成功后即可浏览,你可以在后台->安装扩展功能上传安装插件,在代码调整中点击刷…...
cout源码浅析
目录 cout源码浅析 那么对于没有定义在这之中的要怎么办呢? 实际使用 结语 首先来看我从cplusplus中截取的这张图: 注意最下面这一行字。cout其实是ostream的一个标准对象object。而上面则演示了一些继承关系。 好的,理解了之后…...
发送Ajax get请求详解
发送AJAX get请求,前端代码: <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <title>ajax get请求</title> </head> <body> <script type"text/java…...
SQL语句
创建及删除数据库和表 CREATE DATABASE 数据库名; CREATE DATABASE school; 创建新的表 CREATE TABLE 表名(字段1 数据类型,字段2 数据类型[,...] [,PRIMARY KEY (主键名)]); #主键一般选择能代表唯一性的字段,不允许取空值(NULL),值也不允许重复&…...
Mysql 学习(八)单表查询方法二
复杂查询 上一节说了5种访问类型的查询,这一节就来说说关于这些比较复杂的查询 情况一:多个二级索引查询 sql:SELECT * FROM index_value_table WHERE value1 abc AND value2 > 1000;搜索条件: value1 等于 abcvalue2 大于…...
安卓系统下的截屏和录屏
可以抓取手机屏幕画面(屏幕截图),也可以录制屏幕画面视频。拍摄屏幕后,可以查看、编辑和分享所拍的图片或视频。 抓取屏幕截图 打开要抓取的屏幕。视手机情况执行下列一个操作,3种方法看你手机有效的: 同…...
行为型模式-中介者模式
中介者模式 概述 一般来说,同事类之间的关系是比较复杂的,多个同事类之间互相关联时,他们之间的关系会呈现为复杂的网状结构,这是一种过度耦合的架构,即不利于类的复用,也不稳定。例如在下左图中…...
辅助驾驶功能开发-功能规范篇(16)-2-领航辅助系统NAP-功能ODD定义
1.系统定义 智能驾驶系统包含行车场景功能和泊车场景功能,行车场景功能包括安全ADAS功能、基础ADAS功能和高阶ADAS功能三大类,本文档定义高阶ADAS功能中的导航辅助驾驶功能用例。 1.1.高阶ADAS功能列表 功能需求ID 功能分类 功能名称...
PMP/高项 06-项目成本管理
项目成本管理 概念 项目成本管理 项目成本管理又被称为项目造价管理,是有关项目成本和项目价值两个方面的管理,是为保障以最小的成本实现最大的项目价值而开展的项目专项管理工作。 确保在批准的项目预算内完成项目 成本管理内容 规划成本管理 制定项目…...
XXL-JOB中间件【实现分布式任务调度】
目录 1:XXL-JOB介绍 2:搭建XXL-JOB 2.1:调度中心 2.2:执行器 2.3:执行任务 3:分片广播 1:XXL-JOB介绍 XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速、学…...
Vue3+Element Plus环境搭建和一键切换明暗主题的配置
Vue (发音为 /vjuː/,类似 view) 是一款用于构建用户界面的 JavaScript 框架。而Element Plus是一款基于Vue3面向设计师和开发者的组件库。 最终效果: 环境搭建 已安装 16.0 或更高版本的 Node.js,终端: npm init vuelatest这一…...
Leetcode326. 3 的幂
Every day a leetcode 题目来源:326. 3 的幂 相似题目:342. 4的幂 解法1:递归 代码: /** lc appleetcode.cn id326 langcpp** [326] 3 的幂*/// lc codestart class Solution { public:bool isPowerOfThree(int n){if (n <…...
【运动规划算法项目实战】如何在栅格地图中实现Dijkstra算法
文章目录 简介一、算法介绍1.1 Dijkstra算法流程1.2 Dijkstra算法伪代码二、代码实现2.1 ROS实现2.2 RVIZ演示三、总结简介 Dijkstra算法是一种用于图中单源最短路径的贪心算法。在计算机科学和网络设计中广泛应用。该算法从起点开始,通过优先选择距离起点最近的未标记节点来…...
【算法】一文彻底搞懂ZAB算法
文章目录 什么是ZAB 算法?深入ZAB算法1. 消息广播两阶段提交ZAB消息广播过程 2. 崩溃恢复选举参数选举流程 ZAB算法需要解决的两大问题1. 已经被处理的消息不能丢2. 被丢弃的消息不能再次出现 最近需要设计一个分布式系统,需要一个中间件来存储共享的信息…...
【软考高级】2022年系统分析师综合知识
1.( )是从系统的应用领域而不是从系统用户的特定需要中得出的,它们可以是新的功能性需求,或者是对已有功能性需求的约束,或者是陈述特定的计算必须遵守的要求。 A.功能性需求 B. 用户需求 C.产品需求 D.领域需求 2.对于安全关键系…...
关于AI未来的思考和应用场景
关于AI未来的思考和应用场景 AI(人工智能)是当今最热门的技术领域之一,它已经在多个领域产生了深远的影响,如医疗、金融、制造业等。未来,AI将继续发展,并在更多领域产生重要的影响。 AI的未来发展方向有…...
智慧城市规划数字化管理:数字孪生技术的创新应用
随着智能城市的不断发展,数字孪生技术也开始在智慧城市的建设中得到了广泛应用。数字孪生作为一种数字化的复制技术,它可以模拟真实世界中的实体和过程。 在城市规划方面,数字孪生可以帮助城市规划师更加直观地了解城市的整体规划和发展趋势&…...
开心档之C++ 指针
C 指针 学习 C 的指针既简单又有趣。通过指针,可以简化一些 C 编程任务的执行,还有一些任务,如动态内存分配,没有指针是无法执行的。所以,想要成为一名优秀的 C 程序员,学习指针是很有必要的。 正如您所知…...
零基础搭建私人影音媒体平台【远程访问Jellyfin播放器】
文章目录 1. 前言2. Jellyfin服务网站搭建2.1. Jellyfin下载和安装2.2. Jellyfin网页测试 3.本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置 4.公网访问测试5. 结语 转载自内网穿透工具的文章:零基础搭建私人影音媒体平台【远程访问Jelly…...
Abstract Expressionist
古董地图画集 10大最有名的抽象艺术家 抽象表现主义是现代许多不同艺术思想和表达流派中最奇特的艺术运动之一。这场运动开始从社会变革中涌现出来,恰逢第二次世界大战的最后几周和几个月。 这一次,来自世界各地的人们开始欢迎在经历了多年有史以来最致…...
【郭东白架构课 模块二:创造价值】24|节点四:如何减少语义上的分歧?
你好,我是郭东白。上节课我们通过一个篇幅比较长的电商案例,详细展示了为什么在架构活动中会出现语义分歧。同时也描述了,架构师在统一语义这个环节中所要创造的真正价值是什么。即,看到不同角色之间语境的差异,然后通…...
windows下免费本地部署类ChatGpt的国产ChatGLM-6B
ChatGLM-6B 是一个开源的、支持中英双语的对话语言模型,基于 General Language Model (GLM) 架构,具有 62 亿参数。结合模型量化技术,用户可以在消费级的显卡上进行本地部署(INT4 量化级别下最低只需 6GB 显存)。 Chat…...
flask+opencv+实时滤镜(原图、黑白、怀旧、素描)
简介:滤镜,主要是用来实现图像的各种特殊效果。图像滤镜用于改变图像的视觉效果,使其具有特定的风格。下面是这三种滤镜的详细说明: 1、黑白(Grayscale):黑白滤镜将彩色图像转换为灰度图像&…...
【SCI征稿】极速送审,中科院2区(TOP)计算机算法类SCI,数据库稳定检索19年
算法类: 检索年份:数据库稳定检索19年 自引率:14.50% 国人占比:22.78% 期刊简介:IF:8.0-9.0,JCR1区,中科院2区(TOP) 检索情况:SCI&EI 双…...
1992-2022年31省GDP、第一产业增加值、第二产业增加值 第三产业增加值
1992-2022年31省GDP、第一产业增加值、第二产业增加值 第三产业增加值 1、时间:1992-2022年 2、范围:包括31省 3、指标:省GDP、省第一产业增加值、省第二产业增加值、省第三产业增加值 4、缺失情况说明:无缺失 5、来源&#…...
100种思维模型之万物系统思维模型-57
前面我们介绍过 “万物联系思维模型” ,即万物之间存有各种各样的联系,在解决问题时要看到事物之间的连接,并找到关键的连接,继而快速的解决问题。 01 何谓万物系统思维模型 一、万物系统思维 人的思维习惯, 一…...
Java 中的包装类是什么?如何使用包装类来操作基本数据类型(二十二)
Java 中的包装类是一种特殊的类,用来将基本数据类型(如 int、double、char 等)包装成对象。包装类的作用是可以让基本数据类型具有对象的特性,比如可以作为参数传递给泛型类或方法,可以调用对象的方法,可以…...
【Python入门】Pycharm的使用指南
前言 📕作者简介:热爱跑步的恒川,致力于C/C、Java、Python等多编程语言,热爱跑步,喜爱音乐的一位博主。 📗本文收录于Python零基础入门系列,本专栏主要内容为Python基础语法、判断、循环语句、函…...
python搭建HaIcon物联平台!
Python是一种高级编程语言,易于学习和理解。它在各个领域都有着广泛的应用,例如数据科学、机器学习、爬虫等。 在Python的强大功能之外,Python还有着丰富的第三方库和框架,其中之一就是HaIcon。HaIcon是一种基于Python的物联网平台,它提供了完整的解决方案,包括设备管理…...
一个人做公司管理网站/seo智能优化公司
一、标题title 在浏览器标签处显示的内容,写在html的head部分 <head><title>网页标题</title> </head>二、网页简述description 对网页的一个简单概述,写在html的head部分 <head><meta name"description"…...
深圳网站制作运营/seo广告平台
来自微软中国MSDN关于Scrum的新闻: url: http://msdn.microsoft.com/zh-cn/default.aspx Scrum结合VS2010的认证培训: url: http://msdn.microsoft.com/zh-cn/vstudio/default.aspx 课程介绍 : 课程模块 模块1:介绍 通过这个模…...
在深圳做it的要做赌博网站吗/推广公司app主要做什么
夜光序言: 累,证明自己还没死 正文:...
前端会员中心wordpress/杭州百度开户
【算法分析】 简单而言,将中缀表达式转换为后缀表达式的算法需要注意以下两点。 ● 操作数始终入操作数栈。 ● 操作符入操作符栈时,比较与操作符栈的栈顶元素的优先级,然后选择入操作符栈还是入操作数栈。直至将操作符栈的所有元素入操作数栈…...
如何统计网站pv/推广seo是什么意思
如题。比如乌云社区发帖的这位大牛http://zone.wooyun.org/content/12432 看那帖子标题就很喜感有木有,大概意思就是创建了一个没有file权限的账户test,然后不能load file 啥的,但是可以用load data local 这样来读文件的内容到某个表里&…...
成都网站建设报价/seo实战培训课程
题目描述 煤矿工地可以看成是由隧道连接挖煤点组成的无向图。为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处。于是矿主决定在某些挖煤点设立救援出口,使得无论哪一个挖煤点坍塌之后,其他挖煤点的工人都有一条…...