这两个上下文代码有什么不同?
what is different between theses two context codes?
我在片段中使用 recycderview。
代码 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。效果很好。
我认为这与上下文有关。但是不知道code 1和code 2有什么区别
code 1和code 2不是都有Context吗?
有什么不同?
代码“1”和代码“2”几乎相同,但当未找到 inflater 时,本机实现会抛出错误。我们可以打开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;
}
在Android、LayoutInflater is used to convert an xml file (activity_main.xml
, fragment_login.xml
, gallery_item.xml
, etc.) into its coressponding View对象中。
XML file -> LayoutInflater -> View object in Java
要检索 LayoutInflater
的实例,我们有几种选择:
回到你的问题
代码 1
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
parent
:当前项的父项,在本例中,parent
是 RecyclerView
RecyclerView
是 View
class 的子 class,每个 View
都有自己的上下文,在这种情况下,getContext()
return activity 显示 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,因为它很短。
显然你需要调用这个:
LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
而不是这个:
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
因为 Context
在第一次使用之前可能还没有初始化。保持变量范围尽可能小是一种很好的做法,因此如果您不需要将 onCreateViewHolder
中的 Context
存储在实例变量中,那么就不要。
我在片段中使用 recycderview。 代码 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。效果很好。
我认为这与上下文有关。但是不知道code 1和code 2有什么区别
code 1和code 2不是都有Context吗? 有什么不同?
代码“1”和代码“2”几乎相同,但当未找到 inflater 时,本机实现会抛出错误。我们可以打开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;
}
在Android、LayoutInflater is used to convert an xml file (activity_main.xml
, fragment_login.xml
, gallery_item.xml
, etc.) into its coressponding View对象中。
XML file -> LayoutInflater -> View object in Java
要检索 LayoutInflater
的实例,我们有几种选择:
回到你的问题
代码 1
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
parent
:当前项的父项,在本例中,parent
是 RecyclerView
RecyclerView
是 View
class 的子 class,每个 View
都有自己的上下文,在这种情况下,getContext()
return activity 显示 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,因为它很短。
显然你需要调用这个:
LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
而不是这个:
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
因为 Context
在第一次使用之前可能还没有初始化。保持变量范围尽可能小是一种很好的做法,因此如果您不需要将 onCreateViewHolder
中的 Context
存储在实例变量中,那么就不要。