使用BindView有这样一个特点,即编写好的xml布局文件需要build一下,生成其对应的binding类才能被activity或自定义布局使用,即:activity_main.xml文件编译后生成的类为:ActivityMainBinding.java。
在本人使用的这些日子当中,发现其实BindView这个东西确实没有Butterknife好用!每次编写好的xml需要编译不说,而且经常在使用其编译好的控件时报红!
不过如果你会Kotlin的话,你就不需要学习BindView和Butterknife了,因为Kotlin的使用已经相当简洁和方便了[嗯哼~有点偏题了]
这次文章主要介绍xml文件的控件绑定
步骤
Step 1:在app module下的build.gradle中添加以下代码
android {
compileSdkVersion 28
defaultConfig {
...
}
buildTypes {
...
}
// 添加如下代码
dataBinding {
enabled = true
}
}
Step 2:编写xml文件,需要在布局最外层添加<layout></layout>标签
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
</data>
<android.support.constraint.ConstraintLayout
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">
<TextView
android:id="@+id/hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</layout>
到目前为止,我们的基本任务就完成了,然后需要做的就是编译一下我们的项目,让其生成xml文件对应的类。这个类可以生成我们布局文件中每个组件对应的ID信息,有这个ID信息,我们就能使用这个组件了。
我们看一下生成的这个类
生成的类名根据xml文件的文件名来匹配,例如xml文件名为:activity_main.xml转换成binding类名为:ActivityMainBinding
public class ActivityMainBinding extends android.databinding.ViewDataBinding {
@Nullable
private static final android.databinding.ViewDataBinding.IncludedLayouts sIncludes;
@Nullable
private static final android.util.SparseIntArray sViewsWithIds;
static {
sIncludes = null;
sViewsWithIds = new android.util.SparseIntArray();
sViewsWithIds.put(R.id.hello_world, 1);
}
// views 大家看这里!这里!里!---这个对象就是我们所说的xml里面生成的对应组件
@NonNull
public final android.widget.TextView helloWorld;
@NonNull
private final android.support.constraint.ConstraintLayout mboundView0;
// variables
// values
// listeners
// Inverse Binding Event Handlers
public ActivityMainBinding(@NonNull android.databinding.DataBindingComponent bindingComponent, @NonNull View root) {
super(bindingComponent, root, 0);
final Object[] bindings = mapBindings(bindingComponent, root, 2, sIncludes, sViewsWithIds);
this.helloWorld = (android.widget.TextView) bindings[1];
this.mboundView0 = (android.support.constraint.ConstraintLayout) bindings[0];
this.mboundView0.setTag(null);
setRootTag(root);
// listeners
invalidateAll();
}
@Override
public void invalidateAll() {
synchronized(this) {
mDirtyFlags = 0x1L;
}
requestRebind();
}
@Override
public boolean hasPendingBindings() {
synchronized(this) {
if (mDirtyFlags != 0) {
return true;
}
}
return false;
}
@Override
public boolean setVariable(int variableId, @Nullable Object variable) {
boolean variableSet = true;
return variableSet;
}
@Override
protected boolean onFieldChange(int localFieldId, Object object, int fieldId) {
switch (localFieldId) {
}
return false;
}
@Override
protected void executeBindings() {
long dirtyFlags = 0;
synchronized(this) {
dirtyFlags = mDirtyFlags;
mDirtyFlags = 0;
}
// batch finished
}
// Listener Stub Implementations
// callback impls
// dirty flag
private long mDirtyFlags = 0xffffffffffffffffL;
@NonNull
public static ActivityMainBinding inflate(@NonNull android.view.LayoutInflater inflater, @Nullable android.view.ViewGroup root, boolean attachToRoot) {
return inflate(inflater, root, attachToRoot, android.databinding.DataBindingUtil.getDefaultComponent());
}
@NonNull
public static ActivityMainBinding inflate(@NonNull android.view.LayoutInflater inflater, @Nullable android.view.ViewGroup root, boolean attachToRoot, @Nullable android.databinding.DataBindingComponent bindingComponent) {
return android.databinding.DataBindingUtil.<ActivityMainBinding>inflate(inflater, com.gudong.browser.bindviewapp.R.layout.activity_main, root, attachToRoot, bindingComponent);
}
@NonNull
public static ActivityMainBinding inflate(@NonNull android.view.LayoutInflater inflater) {
return inflate(inflater, android.databinding.DataBindingUtil.getDefaultComponent());
}
@NonNull
public static ActivityMainBinding inflate(@NonNull android.view.LayoutInflater inflater, @Nullable android.databinding.DataBindingComponent bindingComponent) {
return bind(inflater.inflate(com.gudong.browser.bindviewapp.R.layout.activity_main, null, false), bindingComponent);
}
@NonNull
public static ActivityMainBinding bind(@NonNull android.view.View view) {
return bind(view, android.databinding.DataBindingUtil.getDefaultComponent());
}
@NonNull
public static ActivityMainBinding bind(@NonNull android.view.View view, @Nullable android.databinding.DataBindingComponent bindingComponent) {
if (!"layout/activity_main_0".equals(view.getTag())) {
throw new RuntimeException("view tag isn't correct on view:" + view.getTag());
}
return new ActivityMainBinding(bindingComponent, view);
}
/* flag mapping
flag 0 (0x1L): null
flag mapping end*/
//end
}
Step 3: 好了,接下来我们介绍一下如何调用生成的这个类文件
我们先创建一个基类,该基类用于我们对大多数要使用BindView的activity有通用作用。
public abstract class BaseBindActivity<VB extends ViewDataBinding> extends AppCompatActivity {
protected VB mBinding;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 获取视图
View view = getLayoutInflater().inflate(getLayoutResId(), null, false);
// databinding绑定视图
mBinding = DataBindingUtil.bind(view);
setContentView(view);
}
/**
* get layout resource id;
* @return
*/
@LayoutRes
protected abstract int getLayoutResId();
}
Step 4:在MainActivity.java类中继承该基类
public class MainActivity extends BaseBindActivity<ActivityMainBinding> {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView helloworld = mBinding.helloWorld;
helloworld.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"hello world",Toast.LENGTH_SHORT).show();
}
});
}
@Override
protected int getLayoutResId() {
return R.layout.activity_main;
}
}
如此,我们任务就大功告成了。
后面抽时间来介绍一下数据的绑定。
网友评论