持续创作,加速成长!这是我参与「日新计划 6 月更文挑战」的第2天,点击查看活动详情
简介
DataBinding是Google在18年推出的数指针数组和数组指针的区别据绑定框架,采用了MVVM模式来降低各模块之间代码的指针数组和数组指针的区别耦合度,使得整体代码逻辑设计更加清晰。众所周知,MVVM类似于MVC,主要目的是为分离View(视图)和Model(模型),同时进行google谷歌搜索主页双向数据绑定,当业务数据发生改变量泵变时,View能及时刷新;当View数据更新时,同时能同步到Model。同时,DataBinding能省去findViewById()操作,大量减少Activity内代码,根据业务场景,可以让数据能单向或双向绑approach定到对应界面layoapproachut中,能较好的避免空指针,以及防变量值范内存泄漏。
使用
启用方式,指针式万用表使用方法在Module的build.gradle中构建:
android {
...
buildFeatures {
dataBinding true
}
}
1、布局绑定
在要编写的布局文件中选定根布局,按approveAlt+回车快捷键唤出提示:
选择第一个即可生成符合DataBinding规则的布局文件:
<?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>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
...
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
可看见原根布局被包裹住了,且布局元素上方变量名的命名规则出现< dataapproach>标签,在这< data>标签是用于声明要用到的变量以及变量mvvm与mvc类型,在MVVM模式中扮演的是一个View变量值和Model通讯的中间人角色。
生成dataBinding规则的google布局后,数据绑定库会自定生成将布局中的视图和数据绑定所变量名需的类,类名为layout.xml文件名+DataBindinGoogleg的驼峰规则命名组合(这点与ViewBinding类似)。
比如:我这个是MainActivity.classappetite,布局文件为activity_main.xml,则相应变量泵绑定类类名为 ActivitappstoreyMainBinding 。
2、绑定流程
步骤一:先编写一个简单的实体Bean类:
java版:
public class UserInfo {
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private String name;
private int age;
}
kt版:
data class UserInfo(val name: String,val age: Int) {}
步mvvm与mvc骤二:在布局文件中的里引用要使用到的变量名、类的全路径,apple如下:
<data>
<variable
name="UserInfoExample"
type="com.example.dbjavatest.bean.UserInfo" />
</data>
在这里,中的name可以随意命名,但建议跟实体bean类一致,以免后mvvm原理续遗忘;type则为对应实体bean类的全路径
PgoogleS 这里有两个极少数情况:后续你可能发现如果要多出引用这个bean实体类,要写不同的命名区分,就会变成这样:
<data>
<variable
name="UserInfoExample"
type="com.example.dbjavatest.bean.UserInfo" />
<variable
name="UserInfoExample2"
type="com.example.dbjavatest.bean.UserInfo" />
...
</data>
这时候可以通过 import 标签声明所有用到的这个mvvm的理解实体bean类,以上代码即变指针是什么为:
<data>
<import type="com.example.dbjavatest.bean.UserInfo"/>
<variable
name="UserInfoExample"
type="UserInfo" />
<variable
name="UserInfoExample2"
type="UserInfo" />
...
</data>
如果import标mvvm数据双向绑定原理签下两个appearance类名相同,哪怕全路径googleplay安卓版下载不同,这里就要使用 alias来指定别名,如下:
<data>
<import type="com.example.dbjavatest.bean.UserInfo"/>
<import
alias="NewUserInfo"
type="com.example.dbjavatest.otherbean.UserInfo"/>
<variable
name="UserInfoExample"
type="UserInfo" />
<variable
name="UserInfoExample2"
type="NewUserInfo" />
...
</data>
步骤三:在View中引入数据,使用 @{} 语法,类名即为我们在中定义的name:
<?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="UserInfoExample"
type="com.example.dbjavatest.bean.UserInfo" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/tv_user_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{UserInfoExample.name}"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:id="@+id/tv_user_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{UserInfoExample.age}"
app:layout_constraintTop_toBottomOf="@+id/tv_user_first"
app:layout_constraintStart_toStartOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
可以看出,布局文件里变量值,第一个TextView的tex变量的定义t通过@{UserInfoExample.name}引用UserInfo的name属性,第二个TegooglextView的text通过@{UserInfoExample.age}引用UserInfo的age属性。
步骤四:在Activity中实appetite现数据绑定:
java版:mvvm原理面试
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
UserInfo userInfo = new UserInfo("亚历山大", 99);
viewDataBinding.setUserInfoExample(userInfo);
}
}
kt版:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewDataBinding: ActivityMainBinding =
DataBindingUtil.setContentView(this, R.layout.activity_main)
viewDataBinding.userInfoExample = UserInfo("亚历山大", 99)
}
}
可以看到这里不再需要传统的setContentView()指定布局application了。直接通过 DataBindingUtil 设置布局文件并得到对应da指针式万用表taBinding对象,并给相应属性赋值指针式万用表,你可以发现此apple属性的setxxx()并不是bean指针c语言实体类指针说漫名,而是布局中里的name属性名。
一运行,发现,报错:
顺着提示,找下原因,在对应生成的ActivityMainBindingImpl.java类中的116行,如下:
原因就在此,原UserInfo的实例getAge()返回的是int类型,这里setText里只接受Strin指针是什么gMVVM,按此推断,修改原布局文件就可以了。
<TextView
android:id="@+id/tv_user_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{String.valueOf(UserInfoExample.age)}"
app:layout_constraintTop_toBottomOf="@+id/tv_user_first"
app:layout_constraintStart_toStartOf="parent"/>
按上述代码修改对应android:text=“”中的属性,运行后可正常发布:
细心的你可能会发现,xml预览界面中由于没有填写相应数值,致使显示是一片空白。这样不利于我们去观察所设置的变量值TextView颜色大小等属性实际表现结果,这时我们可以去设置默认值来让其在预览界面中显示,格式如下:
android:text="@{UserInfoExample.name,default=defaultValue}"
我们修改原布局中元素属性为:
<TextView
android:id="@+id/tv_user_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{UserInfoExample.name,default=defaultValue}"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<TextView
android:id="@+id/tv_user_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{UserInfoExample.age,default=25}"
app:layout_constraintTop_toBottomOf="@+id/tv_user_first"
app:layout_constraintStart_toStartOf="parent"/>
对MVVM应生成的预览界面为:
3、Activity中使用
跟ViewBinding一样,可通过ActivityMainBinding(你对应的activity的dataBinappetitedinappreciateg类)来获取指定id控件,例如变量与函数:
java版:
viewDataBinding.tvUserFirst.setText("get到了第一个TextView");
kt版:
viewDataBinding.tvUserFirst.text = "get到了第一个TextView"
原布局中,可在< data>标签里指定对应的ViewBinding名称,如果不指定就是默认根据文件名和驼峰原google中国则生成的类名(上面说的ac变量名tivity_变量类型有哪些magoogleplay安卓版下载in.xml和Actimvvm原理面试vityMainBinding)。例如:
<data class="DemoBinding">
...
</data>
指定中的变量英语class后,原activity就已经开始报错了,此时要修改对应的ViewB指针万用表怎么读数inding为 DemoBinding 。原来activity中代码则改为了:
java版:
...
DemoBinding viewDataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
UserInfo userInfo = new UserInfo("亚历山大", 99);
viewDataBinding.setUserInfoExample(userInfo);
...
kt版:
...
val viewDataBinding: DemoBinding =
DataBindingUtil.setContentView(this, R.layout.activity_main)
viewDataBinding.userInfoExample = UserInfo("亚历山大", 99)
...
4、在Fragment和RecyclerView中使用
在Fragment中的使用于Activity类似,这里指针说漫为了方便,Fragment的布局fraggoogleplay安卓版下载ment_main.xm指针说漫l内容就跟原activity_main.xml内容保持一致。其activity_main.xml引用此Fragment的布局就修APP改为(Fragment中id不能省略):
<?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="UserInfoExample"
type="com.example.dbjavatest.bean.UserInfo" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment
android:id="@+id/fragment_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.example.dbjavatest.MainFragment"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Fragment中代变量名码表现则为:
j变量类型有哪些ava:
public class MainFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
FragmentMainBinding viewDataBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_main, container, false);
viewDataBinding.setUserInfoExample("屋大维",99);
return viewDataBinding.getRoot();
}
}
kt:
class MainFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val viewDataBinding: FragmentMainBinding =
DataBindingUtil.inflate(inflater, R.layout.fragment_main, container, false)
viewDataBinding.userInfoExample = UserInfo("屋大维",99)
return viewDataBinding.getRoot()
}
...
}
可见,在Fragment中使用的是 DataBindingUtil对应的inflate(),在onCreateView()中返回mvvm数据双向绑定原理对应ViewBinding.getRoot()。其他使用与在Activitygoogle浏览器中使用一致,这里就不赘述。
同样使用DataBindingUtil.inflate()来获取ViewBinding对象的是RGoogleecyclerView的Adapter中:
java版:
...
@NonNull
@Override
public ViewBindHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
ViewDataBinding inflate = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.item_recyclerview,parent,false);
ViewBindHolder viewHolder = new ViewBindHolder(inflate);
viewHolder.setmViewBing(viewHolder);
return new ViewHolder(inflater);
}
@Override
public void onBindViewHolder(@NonNull ViewBindHolder holder, int position) {
holder.bind(...);//传入的UserInfo
}
static class ViewBindHolder extends RecyclerView.ViewHolder{
private ItemRecyclerviewBinding mViewBing;
public ViewBindHolder(View view){
super(view);
}
public void setmViewBing(ItemRecyclerviewBinding mViewBing) {
this.mViewBing = mViewBing;
}
public void bind(UserInfo userInfo){
mViewBing.setUserInfoExample(userInfo);
}
}
...
kt版:
@NonNull
override fun onCreateViewHolder(@NonNull parent: ViewGroup, viewType: Int): ViewBindHolder? {
val inflate: ViewDataBinding = DataBindingUtil.inflate(
LayoutInflater.from(parent.context),
R.layout.item_recyclerview,
parent,
false
)
val viewHolder = ViewBindHolder(inflate)
viewHolder.setmViewBing(viewHolder)
return RecyclerView.ViewHolder(inflater)
}
override fun onBindViewHolder(@NonNull holder: ViewBindHolder?, position: Int) {
// holder.bind(...);//传入的UserInfo
}
class ViewBindHolder(view: View?) : RecyclerView.ViewHolder(view!!) {
private var mViewBing: ItemRecyclerviewBinding? = null
fun setmViewBing(mViewBing: ItemRecyclerviewBinding?) {
this.mViewBing = mViewBing
}
fun bind(userInfo: UserInfo?) {
mViewBing!!.setUserInfoExample(userInfo)
}
}
在onCreateViewHolder中通过DataBindingUtil去获取相应的dataBinding对象,在ViewHolder中进行binding,其余操作与Activity、Fragment差别不大,这里不再赘述。