在RecyclerView中膨胀两种类型的.XML

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在RecyclerView中膨胀两种类型的.XML相关的知识,希望对你有一定的参考价值。

由于我遇到的这个问题,我感到非常沮丧:如何为RecyclerView中的不同对象充气不同的.XML文件?我做了尽可能多的事情,比如制作一个ListItemType对象:

public class ListItemType {
    public static int NOTE_VIEW = 0;
    public static int CATEGORY_VIEW = 1;
}

还有一个ListViewItem对象:

public class ListViewItem {
    private int mType;
    private Object mObject;

    public ListViewItem(int type, Object object) {
        mType = type;
        mObject = object;
    }

    public int getType() {
        return mType;
    }

    public void setType(int type) {
        mType = type;
    }

    public Object getObject() {
        return mObject;
    }

    public void setObject(Object object) {
        mObject = object;
    }
}

我对从哪里离开这里一无所知。

答案

RecyclerView实施

首先,你必须添加/创建/你的Model类型,表明你的Model类型,并知道要膨胀的布局:

my model.Java

public class MyModel {
    public enum ModelTypes {
        TYPE_1,
        TYPE_2
    }
    // your model members ^^^

    ModelTypes type;
}

现在你必须创建你的ViewHolder,我建议创建一个父ViewHolder类并使用子类扩展你的模型类型。

my holder.Java

public class MyHolder extends RecyclerView.ViewHolder {

    // must have the ViewHolder default constructor
    public MyHolder(View itemView) {
        super(itemView);
    }

    public static MyHolder inflateViewByType(MyModel.ModelTypes type, 
                                            LayoutInflater layoutInflater, ViewGroup parent) {
        View view;
        switch (type) {
            case TYPE_1:
                view = layoutInflater.inflate(R.layout.layout_type_1, parent, false);
                return new MyHolderType1(view);
            break;
            case TYPE_2:
                view = layoutInflater.inflate(R.layout.layout_type_2, parent, false);
                return new MyHolderType2(view);
            break;
        }
        // Model type not supported
        return null;
    }
}

创建你的ViewHolder类型,在我的例子中我只有两种类型。

my holder type1.Java

public class MyHolderType1 extends MyHolder {

    // layout members

    public MyHolderType1(View itemView) {
        super(itemView);
        // init your layout members by for layout_type_1 by itemView.findViewById(...)
    }
}

my holder type2.Java

public class MyHolderType2 extends MyHolder {

    // layout members

    public MyHolderType2(View itemView) {
        super(itemView);
        // init your layout members by for layout_type_2 by itemView.findViewById(...)
    }
}

到目前为止,您只需创建ViewHolder类型来实现RecyclerViewRecyclerView必须有一个扩展默认AdapterRecyclerView.Adapter,为此我们必须创建一个新类并用RecyclerView.Adapter扩展ViewHolder

my recycler view adapter.Java

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyHolder> {

    private List<MyModel> mData;

    public MyRecyclerViewAdapter(@NonNull List<MyModel> data) {
        mData = data;
    }

    @Override
    public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        MyModel.ModelTypes type = MyModel.ModelTypes.values()[viewType];
        return MyHolder.inflateViewByType(type, layoutInflater, parent);
    }

    @Override
    public void onBindViewHolder(MyHolder holder, int position) {

        MyModel model = mData.get(position);
        switch (model.type) {
            case TYPE_1:
                setupViewType1((MyHolderType1) holder, model);
                break;
            case TYPE_2:
                setupViewType2((MyHolderType2) holder, model);
                break;
        }
    }

    // to update the adapter data without reinitialize it
    public void updateData(@NonNull List<MyModel> newData) {
        mData = newData;
        notifyDataSetChanged();
    }

    private void setupViewType1(MyHolderType1 holder, MyModel model) {

        // do what you want with your views in layout_type_1
    }

    private void setupViewType2(MyHolderType2 holder, MyModel model) {

        // do what you want with your views in layout_type_2
    }

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

    @Override
    public int getItemViewType(int position) {
        return mData.get(position).type.ordinal();
    }
}

继续前进,我们差不多完成了。现在我们必须在我们的活动中初始化RecyclerView,并将MyRecyclerViewAdapter的实例设置为它。为此我们通过调用RecyclerView找到findViewById(...) in和xml,然后将LayoutManager设置为RecyclerView,毕竟我们用我们的数据设置了适配器。

my activity.Java

public class MyActivity extends Activity{

    // ....

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_layout);


        // init your views
        RecyclerView recyclerView = findViewById(R.id.recycler_view);


        // here you can pull or generate your recycler view list data
        List<MyModel> data = getData();
        MyRecyclerViewAdapter adapter = new MyRecyclerViewAdapter(data);


        // set layout manager to the recycler view (Required)
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, 
                                                        LinearLayoutManager.VERTICAL, false);
        recyclerView.setLayoutManager(linearLayoutManager);

        // set the adapter to the recycler view (Required)
        recyclerView.setAdapter(adapter);
    }

    // ....
}

以上是关于在RecyclerView中膨胀两种类型的.XML的主要内容,如果未能解决你的问题,请参考以下文章

Recyclerview 和处理不同类型的行膨胀

Recyclerview 和处理不同类型的行膨胀

在 RecyclerView 上膨胀类 ImageView 时出错

膨胀类 android.support.v7.widget.RecyclerView 时出错

片段没有被 RecyclerView 膨胀

如何根据其在 onCreateViewHolder 方法中的位置在 RecyclerView 中膨胀不同的布局