RecyclerView详细介绍-----多item布局(三)

来源:互联网 发布:量产后数据如何恢复 编辑:程序博客网 时间:2024/05/16 10:38

1.前言

前面两篇文章主要介绍了recyclerview的基本使用,接下来介绍复杂一点的需求。
我们之前用listview的时候肯定遇到itemType>1的时候,我们定义多套item布局,借助getItemViewType()实现多套布局。但是如果像淘宝首页,上面是listview的一个一个item,下面确是一个GridView的话,我们如何实现呢?当然之前有人会把GridView用ListView来实现,及一个Listview的item来代替GridView的两个item,只是数据集我们要自己做处理,总之很麻烦。现在有了recyclerview,这些就变得很简单。

2.实现效果

这里写图片描述
上图既有listview的列表,下方又有gridview,如何实现呢?

3.具体实现过程:

1)跟listview一样,recyclerview借助getItemViewType(int position)实现多套布局判断,然后根据itemtype实现多套布局的创建跟赋值,具体代码如下:

public class MultiItemAdapter extends RecyclerView.Adapter<MultiItemAdapter.ViewHolder> {    public static final int ONE_TEXT_VIEW_TYPE = 0;    public static final int TWO_TEXT_VIEW_TYPE = 1;    public static final int GRID_VIEW_TYP = 2;    private ArrayList<Person> data;    private Context context;    public MultiItemAdapter(Context context, ArrayList<Person> data) {        this.data = data;        this.context = context;    }    @Override    public int getItemViewType(int position) {        if (data.get(position).getType() == ONE_TEXT_VIEW_TYPE) {            return ONE_TEXT_VIEW_TYPE;        } else if (data.get(position).getType() == TWO_TEXT_VIEW_TYPE) {            return TWO_TEXT_VIEW_TYPE;        } else if (data.get(position).getType() == GRID_VIEW_TYP) {            return GRID_VIEW_TYP;        }else {            return  ONE_TEXT_VIEW_TYPE;        }    }    @Override    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {        View itemView = null;        switch (viewType) {            case ONE_TEXT_VIEW_TYPE:                itemView = LayoutInflater.from(this.context).inflate(R.layout.multi_item_one, null);                break;            case TWO_TEXT_VIEW_TYPE:                itemView = LayoutInflater.from(this.context).inflate(R.layout.multi_item_two, null);                break;            case GRID_VIEW_TYP:                itemView = LayoutInflater.from(this.context).inflate(R.layout.multi_item_three, null);                break;        }        return new ViewHolder(itemView);    }    @Override    public void onBindViewHolder(ViewHolder holder, int position) {        int itemViewType = getItemViewType(position);        switch (itemViewType) {            case ONE_TEXT_VIEW_TYPE:                showOneTextView(holder, position);                break;            case TWO_TEXT_VIEW_TYPE:                showTwoTextView(holder, position);                break;            case GRID_VIEW_TYP:                showGridView(holder, position);                break;        }    }    /**     * 赋值     *     * @param holder     * @param position     */    private void showOneTextView(ViewHolder holder, int position) {        TextView textview = (TextView) holder.findViewById(R.id.item_text);        textview.setText(data.get(position).getName());    }    private void showTwoTextView(ViewHolder holder, int position) {        TextView item_text_one = (TextView) holder.findViewById(R.id.item_text_one);        TextView item_text_two = (TextView) holder.findViewById(R.id.item_text_two);        item_text_one.setText(data.get(position).getName());        item_text_two.setText(data.get(position).getType() + "");    }    private void showGridView(ViewHolder holder, int position) {        TextView textview = (TextView) holder.findViewById(R.id.item_text);        textview.setText(data.get(position).getName());    }    @Override    public int getItemCount() {        return data == null ? 0 : data.size();    }    //自定义的ViewHolder,持有每个Item的的所有界面元素    public static class ViewHolder extends RecyclerView.ViewHolder {        private Map<Integer, View> mCacheView;        public ViewHolder(View itemView) {            super(itemView);            mCacheView = new HashMap<>();        }        public View findViewById(int resId) {            View view;            if (mCacheView.containsKey(resId)) {                view = mCacheView.get(resId);            } else {                view = itemView.findViewById(resId);                mCacheView.put(resId, view);            }            return view;        }    }}

这里需要说一下,ViewHolder 我们这边统一做了封装,抽出findViewById方法,内部做了缓存处理,而简单的具体实例化交给各个具体item,方便使用。
2)我们知道普通的listview只有一列,而gridview是多列,recyclerview如何做到呢?其实是用到了layoutManager.setSpanSizeLookup方法.

public class MultiItemActivity extends AppCompatActivity {    /**     * view     */    private RecyclerView recyclerView;    /**     * 用来确定每一个item如何进行排列摆放,何时展示和隐藏     */    private GridLayoutManager layoutManager;    /**     * 适配器     */    private MultiItemAdapter mAdapter;    private ArrayList<Person> data = new ArrayList<Person>();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();        initData();    }    /**     * 初始化布局组件     */    private void initView() {        recyclerView = (RecyclerView) findViewById(R.id.recycler_view);        //创建默认的线性LayoutManager        layoutManager = new GridLayoutManager(this, 2);        recyclerView.setLayoutManager(layoutManager);        //如果可以确定每个item的高度是固定的,设置这个选项可以提高性能        recyclerView.setHasFixedSize(true);    }    /**     * 初始化数据     */    private void initData() {        for (int i = 0; i < 10; i++) {            Person person = new Person();            person.setName(i + "abc" + 1);            if (i < 3) {                person.setType(MultiItemAdapter.ONE_TEXT_VIEW_TYPE);            } else if (i < 6) {                person.setType(MultiItemAdapter.TWO_TEXT_VIEW_TYPE);            } else {                person.setType(MultiItemAdapter.GRID_VIEW_TYP);            }            data.add(person);        }        //创建并设置Adapter        mAdapter = new MultiItemAdapter(this, data);        recyclerView.setAdapter(mAdapter);        recyclerView.setItemAnimator(new DefaultItemAnimator());        layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {            @Override            public int getSpanSize(int position) {                if (mAdapter.getItemViewType(position)                        == MultiItemAdapter.GRID_VIEW_TYP) {                    return 1;                } else {                    return 2;                }            }        });    }}

在上面的基本设置中,我们的spanCount为2,setSpanSizeLookup可以让你根据position来设置spanCount,spanCount可以想象成布局里面的weight(比重),原先通过layoutManager = new GridLayoutManager(this, 2);设置成一个item占比为2,那么如果根据setSpanSizeLookup设置的spanCount为1的话,那么一行就是2列,这样才能满足一行的比重为2;如果spanCount为2的话,则说明一行一列。
通过上面的代码,我们就轻松的实现了多itemtype甚至listview跟gridview混合的情况。

4.完整代码下载地址如下所示:

demo下载链接

欢迎一起交流讨论
群号:469890293

2 0
原创粉丝点击