Java 什么是RecyclerView.Adapter<;MyAdapter.MyViewHolder>;它与Android中的RecyclerView.Adapter有何不同?
我正在学习RecyclerView,在的站点中,Adapter类扩展了Java 什么是RecyclerView.Adapter<;MyAdapter.MyViewHolder>;它与Android中的RecyclerView.Adapter有何不同?,java,android,android-recyclerview,Java,Android,Android Recyclerview,我正在学习RecyclerView,在的站点中,Adapter类扩展了RecyclerView.Adapter。实施情况表明: public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> { private String[] mDataset; public static class MyViewHolder extends RecyclerView.ViewHolder { p
RecyclerView.Adapter
。实施情况表明:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private String[] mDataset;
public static class MyViewHolder extends RecyclerView.ViewHolder {
public TextView textView;
public MyViewHolder(TextView v) {
super(v);
textView = v;
}
}
public MyAdapter(String[] myDataset) {
mDataset = myDataset;
}
@Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
TextView v = (TextView) LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_text_view, parent, false);
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.textView.setText(mDataset[position]);
}
@Override
public int getItemCount() {
return mDataset.length;
}
}
那么,RecyclerView.Adapter
和RecyclerView.Adapter
之间的区别是什么?在这种情况下,RecyclerView.Adapter
中的语法是什么意思?我知道它代表泛型。我什么时候用这个
那么,RecyclerView.Adapter适配器类的定义。它在RecyclerView
中定义如下:
public abstract static class Adapter<VH extends ViewHolder>
或者,您发布的教程不指定类型
public class SimpleAdapter extends RecyclerView.Adapter
当您扩展一个需要泛型类型而不指定泛型类型的类时,编译器默认使用最小公分母,即继承层次结构中保证该类可以按设计使用的最小类类型。由于适配器的泛型类型定义为VH extends ViewHolder
,编译器知道类类型必须至少是ViewHolder
,并且默认为该类型。因此,本例覆盖的相同方法返回RecyclerView.ViewHolder
,而不是MyViewHolder
:
@Override
public RecyclerView.ViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
final View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
return new SimpleViewHolder(view);
}
如果将RecyclerView.Adapter
定义为Adapter
(无边界类型),并且您在未指定类型的情况下对其进行了扩展,则该类型将默认为Object
(所有Java类的根类):
那么,最后,为什么要用一个而不是另一个呢?一般来说:应该始终为泛型类指定类型。这保证了键入的安全性。在本教程示例中,您可能返回错误类型的视图持有者,该持有者将编译,但在运行时崩溃:
@Override
public RecyclerView.ViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
final View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
// Returning wrong view holder, but because it still extends ViewHolder and
// that is all this method requires, this compiles
return new SomeOtherViewHolder(view);
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
// Above we created a SomeOtherViewHolder but here we're expecting a SimpleViewHolder
// This will crash trying to cast to the wrong type
((SimpleViewHolder) holder).bindData(models.get(position));
}
但在第一个示例中不可能犯此错误,因为ViewHolder
类型是显式声明的:
@Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
TextView v = (TextView) LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_text_view, parent, false);
// Trying to return SomeOtherViewHolder when method expects MyViewHolder
// Compiler's like (*waves finger*) "nuh-uh, not on my watch" and fails
// to compile
SomeOtherViewHolder vh = new SomeOtherViewHolder(v);
return vh;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
// Notice here that holder is explicitly of MyViewHolder type and casting
// is not necessary! That's TYPE SAFETY y'all.
holder.textView.setText(mDataset[position]);
}
由于指定了所需的显式具体类型,因此不能意外返回错误的类型,不需要强制转换,并且可以利用自定义ViewHolder
类中定义的所有公共方法
希望有帮助 如果类是泛型类型,则应始终指定类型参数。所以我应该使用“公共类SimpleAdapter扩展RecyclerView.Adapter”而不是“公共类SimpleAdapter扩展RecyclerView.Adapter”?这两种方法都可以,您应该使用第一种方法,尽管您显然会用应用程序正在使用的任何类型替换类型参数。虽然这两种方法都有效,但它们并不等价,第二种是原始类型。有关原始类型的更多信息,以及为什么应该避免原始类型,请参见我在前面的评论中链接的Q&A。
@Override
public Object onCreateViewHolder(final ViewGroup parent, final int viewType) {
final View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
return new SimpleViewHolder(view);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
final View view = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
// Returning wrong view holder, but because it still extends ViewHolder and
// that is all this method requires, this compiles
return new SomeOtherViewHolder(view);
}
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
// Above we created a SomeOtherViewHolder but here we're expecting a SimpleViewHolder
// This will crash trying to cast to the wrong type
((SimpleViewHolder) holder).bindData(models.get(position));
}
@Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
TextView v = (TextView) LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_text_view, parent, false);
// Trying to return SomeOtherViewHolder when method expects MyViewHolder
// Compiler's like (*waves finger*) "nuh-uh, not on my watch" and fails
// to compile
SomeOtherViewHolder vh = new SomeOtherViewHolder(v);
return vh;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
// Notice here that holder is explicitly of MyViewHolder type and casting
// is not necessary! That's TYPE SAFETY y'all.
holder.textView.setText(mDataset[position]);
}