Java 什么是RecyclerView.Adapter<;MyAdapter.MyViewHolder>;它与Android中的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类扩展了
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.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]);
}