0
点赞
收藏
分享

微信扫一扫

studio3,2年以上经验必看

编程练习生J 2022-01-24 阅读 68

android:layout_width=

“match_parent”

android:layout_height=

“match_parent”

tools:context=

“.MainActivity”>

<TextView

android:id=

“@+id/tv_text”

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” />

<include

android:id=

“@+id/layout_include”

layout=

“@layout/layout_comment” />

</androidx.constraintlayout.widget.ConstraintLayout>

那么此时我们如何使用到layout_comment.xml布局中的TextView控件呢,首先include标签需要声明id,例如layout_include,然后Activity中代码如下:

mBinding.layoutInclude.tvInclude.setText("这就是你的不对了");

是不是很神奇,是不是很简单。

注意:

当你给layout_comment.xml的根布局再添加id(比如添加了layout_xxx的ID)的时候,此时会报错:

java.lang.NullPointerException: Missing required view with ID: layout_xxx

3.3.2、布局中使用include和merge

我们将上文的layout_comment.xml稍作修改,根布局使用merge标签,其他不做修改:

<?xml version= "1.0" encoding= "utf-8"?>

<merge xmlns:android=

“http://schemas.android.com/apk/res/android”

android:layout_width=

“match_parent”

android:layout_height=

“wrap_content”>

<TextView

android:id=

“@+id/tv_include”

android:text=

“这就是测试啊”

android:gravity=

“end”

android:layout_width=

“match_parent”

android:layout_height=

“match_parent” />

<?xml version= "1.0" encoding= "utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout 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”

android:layout_width=

“match_parent”

android:layout_height=

“match_parent”

tools:context=

“.MainActivity”>

<include

android:id=

“@+id/layout_include”

layout=

“@layout/layout_comment” />

</androidx.constraintlayout.widget.ConstraintLayout>

activity_main.xml文件中使用include添加该布局后,在java代码中依旧是可以正常使用以下代码的:

mBinding.layoutInclude.tvInclude.setText("会不会出现问题呀");

但是但是!!!运行就会报错:

java.lang.NullPointerException: Missing required view with ID: layoutInclude

要是把include标签的id去掉的话,这时mBinding中也是找不到tvInclude这个控件呀,怎么办??

之前是不是说过,每个layout文件都会对应一个Binding文件,那么layout_comment.xml,肯定也有一个LayoutCommentBinding.java文件,我们去看下这个文件的源代码,里面有个可疑的方法,bind()方法:

@NonNull

public static LayoutCommentBinding bind(@NonNull View rootView) {

// The body of this method is generated in a way you would not otherwise write.

// This is done to optimize the compiled bytecode for size and performance.

String missingId;

missingId: {

TextView tvInclude = rootView.findViewById(R.id.tv_include);

if (tvInclude ==

null) {

missingId =

“tvInclude”;

break missingId;

}

return

new LayoutCommentBinding(rootView, tvInclude);

}

throw

new NullPointerException(

"Missing required view with ID: ".concat(missingId));

}

所以对于含有merge标签的布局我们可以使用bind()方法来绑定到根布局上,在这里,根布局就是mBinding.getRoot()了。所以代码如下:

//这么写不可以

//mBinding.layoutInclude.tvInclude.setText(“会不会出现问题呀”);

LayoutCommentBinding commentBinding = LayoutCommentBinding.bind(mBinding.getRoot());

commentBinding.tvInclude.setText(

“这就不会出现问题了吧”);

同时需要注意: include标签不可以有id

3.4、Fragment中使用ViewBinding

在Fragment的**onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)**方法中:

//原来的写法

return inflater.inflate(R.layout.fragment_blank, container,

false);

//使用ViewBinding的写法

mBinding = FragmentBlankBinding.inflate(inflater);

return mBinding.getRoot();

拿到FragmentBlankBinding的对象后,更新数据的都和之前一样了。

3.5、自定义View中使用ViewBinding

这里直接贴出来代码吧,就是自定义了一个Fragment然后往其中添加了一个布局,该布局是上文的layout_comment.xml文件,会生成一个对应的LayoutCommentBinding.java文件,同样可以直接使用:

public

class MyView extends FrameLayout {

LayoutCommentBinding commentBinding;

public MyView(@NonNull Context context) {

this(context,

null);

}

public MyView(@NonNull Context context, @Nullable AttributeSet attrs) {

this(context, attrs,

0);

}

public MyView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

initLayout();

}

private void initLayout() {

//之前的写法

//View view = LayoutInflater.from(getContext()).inflate(R.layout.layout_comment, this, false);

//addView(view);

//使用ViewBinding的写法

commentBinding = LayoutCommentBinding.inflate(LayoutInflater.from(getContext()),

this,

false);

addView(commentBinding.getRoot());

}

public void setText(String str) {

commentBinding.tvInclude.setText(str);

}

}

3.6、Adapter中使用ViewBinding

在RecyclerView结合Adapter的例子中我们再使用ViewBinding来尝试下,直接贴Adapter的代码:

public

class MainAdapter extends RecyclerView.Adapter<MainAdapter.ViewHolder> {

private List mList;

public MainAdapter(List list) {

mList = list;

}

@NonNull

@Override

this(context,

null);

}

public MyView(@NonNull Context context, @Nullable AttributeSet attrs) {

this(context, attrs,

0);

}

public MyView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

initLayout();

}

private void initLayout() {

//之前的写法

//View view = LayoutInflater.from(getContext()).inflate(R.layout.layout_comment, this, false);

//addView(view);

//使用ViewBinding的写法

commentBinding = LayoutCommentBinding.inflate(LayoutInflater.from(getContext()),

this,

false);

addView(commentBinding.getRoot());

}

public void setText(String str) {

commentBinding.tvInclude.setText(str);

}

}

3.6、Adapter中使用ViewBinding

在RecyclerView结合Adapter的例子中我们再使用ViewBinding来尝试下,直接贴Adapter的代码:

public

class MainAdapter extends RecyclerView.Adapter<MainAdapter.ViewHolder> {

private List mList;

public MainAdapter(List list) {

mList = list;

}

@NonNull

@Override

举报

相关推荐

0 条评论