我在片段中使用recyclederview。代码1和代码2之间有什么不同?当我第一次使用代码2和代码3时,出现了一个错误。
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext()); // code 1
// LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); // code 2
context = parent.getContext(); //code 3
View itemView = inflater.inflate(R.layout.gallery_item, parent, false);
return new ViewHolder(itemView);
}
错误
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
at com.example.bstcproject.adapter.GalleryAdapter.onCreateViewHolder(GalleryAdapter.java:43)
at com.example.bstcproject.adapter.GalleryAdapter.onCreateViewHolder(GalleryAdapter.java:23)
我留下了代码3,我使用了代码1而不是代码2。效果很好。
我认为这与上下文有关。但我不知道代码1和代码2有什么不同。
代码1和代码2不是都有上下文吗?有什么不同?
在Android中,Layout充气器用于将xml文件(activity_main.xml
、fragment_login.xml
、gallery_item.xml
等(转换为其核心绑定视图对象。
XML文件->布局充气装置->在Java 中查看对象
要检索LayoutInflater
的实例,我们有几个选项:
-
布局充气器。来自(上下文(
-
Context.getSystemService(字符串(
-
Activity.getLayout充气机((
返回您的问题
代码1
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
parent
:当前项的父项,在这种情况下,parent
是RecyclerView
RecyclerView
是View
类的一个子类,每个View
都有自己的上下文,在这种情况下,getContext()
返回显示RecyclerView
的活动。
代码2
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
在Android中,初始化Adapter的实例时,我们通常通过构造函数传递Context实例,如下所示。
class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<Data> data;
public MyAdapter(Context context, List<Data> data) {
this.context = context;
this.data = data;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.gallery_item, parent, false);
return new ViewHolder(itemView);
}
}
在您的情况下,因为您没有为context
分配任何值,所以编译器会抛出该错误。
代码3
context = parent.getContext();
在这种情况下,您不需要通过构造函数传递Context
,只需使用parent
中的上下文即可。
class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Data> data;
public MyAdapter(List<Data> data) {
this.data = data;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View itemView = inflater.inflate(R.layout.gallery_item, parent, false);
return new ViewHolder(itemView);
}
}
在onBindViewHolder()
中,有3个选项可以检索LayoutInflater
:的实例
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Context context = parent.getContext();
// Option 1
LayoutInflater inflater = LayoutInflater.from(context);
// Option 2
LayoutInflater inflater2 = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Option 3
LayoutInflater inflater3 = ((Activity) context).getLayoutInflater();
View itemView = inflater.inflate(R.layout.gallery_item, parent, false);
return new ViewHolder(itemView);
}
我总是选择选项1,因为它很短。
代码'1'和代码'2'几乎相同,但当找不到充气程序时,本机实现会抛出错误。我们可以打开LayoutInfalter.from
方法实现并检查它:
/**
* Obtains the LayoutInflater from the given context.
*/
public static LayoutInflater from(Context context) {
LayoutInflater LayoutInflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (LayoutInflater == null) {
throw new AssertionError("LayoutInflater not found.");
}
return LayoutInflater;
}
显然你需要调用这个:
LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
而不是这个:
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
由于Context
在首次使用之前可能尚未初始化。保持变量的范围尽可能紧凑是一种很好的做法,所以如果您不需要将onCreateViewHolder
中的Context
存储在实例变量中,那么就不要了。