什么是RecyclerView.Adapter ,与Android中的RecyclerView.Adapter有何不同?

问题描述 投票:0回答:1

我正在学习RecyclerView,在developer的站点中,Adapter类扩展了RecyclerView.Adapter<MyAdapter.MyViewHolder>。实现显示:

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;
}
}

并且在此tutorial中,适配器类扩展了RecyclerView.Adapter。实现是:

public class SimpleAdapter extends RecyclerView.Adapter {

private List<SimpleViewModel> models = new ArrayList<>();


public SimpleAdapter(final List<SimpleViewModel> viewModels) {
    if (viewModels != null) {
        this.models.addAll(viewModels);
    }
}


@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);
}


@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {
    ((SimpleViewHolder) holder).bindData(models.get(position));
}


@Override
public int getItemCount() {
    return models.size();
}


@Override
public int getItemViewType(final int position) {
    return R.layout.item_simple_itemview;
}
}

那么RecyclerView.Adapter<MyAdapter.MyViewHolder>RecyclerView.Adapter之间有什么区别?在这种情况下,RecyclerView.Adapter<MyAdapter.MyViewHolder>中的语法<>是什么意思?我知道它代表泛型。我什么时候应该使用它?

java android android-recyclerview recycler-adapter
1个回答
1
投票

那么RecyclerView.Adapter 和RecyclerView.Adapter有什么区别?在这种情况下,RecyclerView.Adapter中的语法<>是什么?我知道它代表泛型。我什么时候应该使用它?

首先,让我们回顾一下Adapter类的定义。它在RecyclerView中的定义如下:

public abstract static class Adapter<VH extends ViewHolder>

那么,“泛型”部分是什么意思?这意味着Adapter类对某些类类型(VH)进行操作,该类类型必须是类ViewHolder的后代。这称为Bounded Type,并确保适配器正在使用的类的类型保证为ViewHolder的类型。

正如您在发布的开发人员网站上的示例中所看到的那样,当创建自己的适配器以将ViewHolder的类型指定为MyViewHolder时,必须在适配器中重写的方法在其签名中显式声明该类型。 。例如,onCreateViewHolder的返回类型显式设置为MyViewHolder

@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;
}

或者,您发布的教程没有[[not

指定类型。public class SimpleAdapter extends RecyclerView.Adapter
当扩展一个需要通用类型的类而未指定一个类型时,

编译器默认为最小公分母

-也就是说,在继承层次结构中最低的类类型将保证该类可以是按设计使用。因为适配器的通用类型定义为VH extends ViewHolder,所以编译器知道类类型必须为[[至少
a 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<VH>(无边界类型),并且在未指定类型的情况下对其进行了扩展,则该类型将默认为Object(所有Java类的根类):
@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)); }

尽管在第一个示例中不可能犯此错误,因为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]);
}

因为您指定了期望的

explicit

concrete

类型,所以您不会意外返回错误的类型,不需要强制转换,并且可以利用自定义[ C0]类。
希望有帮助!
© www.soinside.com 2019 - 2024. All rights reserved.