您的位置:首页 > 其它

base-adapter-helper之recyclerview版本,支持多种viewtype布局

2015-09-09 00:12 633 查看
转载请标明出处:

/article/1825739.html

本文出自:海龙的博客

概述

base-adapter-helper是一个非常不错的封装了BaseAdapter的库,极大简化了写适配器的时间,但是有一个问题,那就是只支持listview、gridview等组件,不支持最近非常火的recyclerview组件,这里模仿着base-adapter-helper封装了一个支持recyclerview的,看下面效果图,一种是重写Recyclerview.Adapter写的普通Adapter类型,下面两种都是通过封装的这个QuickAdapter写的,虽然效果一样,但是代码量大大缩短了,仅仅通过几行代码就可以实现

效果图



3 . 之前通过recyclerview写数据列表,需要一个繁琐的Adapter文件,你之前的代码可能是这样的

package com.hhl.recyclerview.demo.adapter;

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.hhl.recyclerview.demo.R;
import com.hhl.recyclerview.demo.entity.Person;
import com.nostra13.universalimageloader.core.ImageLoader;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by HanHailong on 15/9/7.
 */
public class PersonAdapter extends RecyclerView.Adapter<PersonAdapter.ViewHolder> {

    private List<Person> dataList = new ArrayList<>();

    /**
     * @param list
     */
    public void addAll(List<Person> list) {
        if (list == null) return;
        dataList.addAll(list);
        notifyDataSetChanged();
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_item, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Person person = dataList.get(position);
        if (person == null) return;
        holder.usernameTv.setText(person.getUsername());
        holder.ageTv.setText(person.getAge() + "岁");
        holder.descTv.setText(person.getDesc());
        ImageLoader.getInstance().displayImage(person.getAvatar(), holder.avatarIv);
    }

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

    public static class ViewHolder extends RecyclerView.ViewHolder {

        TextView usernameTv, ageTv, descTv;
        ImageView avatarIv;

        public ViewHolder(View itemView) {
            super(itemView);
            usernameTv = (TextView) itemView.findViewById(R.id.tv_username);
            ageTv = (TextView) itemView.findViewById(R.id.tv_age);
            descTv = (TextView) itemView.findViewById(R.id.tv_desc);
            avatarIv = (ImageView) itemView.findViewById(R.id.iv_avatar);
        }
    }
}


需要这样写一个适配器文件,其中,里面的onCreateViewHolder、onBindViewHolder、getItemCount是必须要实现的,并且你还要自己写一个继承RecyclerView.ViewHolder的静态ViewHolder,如果是含有多个ViewType的,那就更麻烦了。下面看在页面上是怎么使用这个我们刚刚写的PersonAdapter的

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

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));

        mAdapter = new PersonAdapter();

        recyclerView.setAdapter(mAdapter);

        initData();
    }


在onCreate方法里面调用Recyclerview的setAdapter方法,然后initData方法里面填充数据

/**
     * 初始化数据
     */
    private void initData() {
        List<Person> list = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            Person person = new Person();
            person.setUsername("小明测试" + i);
            person.setAge(i);
            person.setDesc("我是一名小学生,今年刚上3年级,我的理想是当一名科学家!");
            if (i % 4 == 0) {
                person.setAvatar("http://f.hiphotos.baidu.com/image/pic/item/cdbf6c81800a19d8218dbbd436fa828ba71e4650.jpg");
            } else if (i % 4 == 1) {
                person.setAvatar("http://i7.hexunimg.cn/2015-08-18/178405037.jpg");
            } else if (i % 4 == 2) {
                person.setAvatar("http://img3.cache.netease.com/photo/0003/2015-08-11/B0NTII0000B70003.jpg");
            } else if (i % 4 == 3) {
                person.setAvatar("http://img5.cache.netease.com/hebei/2015/8/17/20150817152654f2082_500.jpg");
            }
            list.add(person);
        }
        mAdapter.addAll(list);
    }


这样就大公告成了,看下效果图:




但是你没发现我为了写一个列表费了多大劲,每次都得专门写一个adapter,我如果有十几个甚至几十个页面都是展示列表数据的,我需要写十几个、几十个这样的adapter文件,而且很多代码都是重复的,你感觉是不是要疯掉了,下面我们看看quickadapter的魅力之处(不需要专门再写一个Adapter喽)

4 . 再看封装之后的QuickAdapter

1)、先看只有一个ViewType的,还是实现我们刚才的效果

首先呢,我们要再写一个Activity,onCreate里面的代码是这样的:

private QuickAdapter<Person> mQuickAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_single);
        getSupportActionBar().setTitle("单一类型的Item");
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));

        mQuickAdapter = new QuickAdapter<Person>(this, R.layout.single_item) {
            @Override
            protected void convert(BaseAdapterHelper helper, Person item) {
                helper.setText(R.id.tv_username, item.getUsername())
                        .setText(R.id.tv_age, item.getAge() + "岁")
                        .setText(R.id.tv_desc, item.getDesc());
                ImageLoader.getInstance().displayImage(item.getAvatar(), helper.getImageView(R.id.iv_avatar));
            }
        };

        recyclerView.setAdapter(mQuickAdapter);

        initData();
    }


这样就写完一个QuickAdapter了,不需要再写别的其他东西了,只要在填充上数据就可以了,initData方法和我们上面的那个一模一样,看代码如下:

/**
     * 初始化数据
     */
    private void initData() {
        List<Person> list = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            Person person = new Person();
            person.setUsername("小明测试" + i);
            person.setAge(i);
            person.setDesc("我是一名小学生,今年刚上3年级,我的理想是当一名科学家!");
            if (i % 4 == 0) {
                person.setAvatar("http://f.hiphotos.baidu.com/image/pic/item/cdbf6c81800a19d8218dbbd436fa828ba71e4650.jpg");
            } else if (i % 4 == 1) {
                person.setAvatar("http://i7.hexunimg.cn/2015-08-18/178405037.jpg");
            } else if (i % 4 == 2) {
                person.setAvatar("http://img3.cache.netease.com/photo/0003/2015-08-11/B0NTII0000B70003.jpg");
            } else if (i % 4 == 3) {
                person.setAvatar("http://img5.cache.netease.com/hebei/2015/8/17/20150817152654f2082_500.jpg");
            }
            list.add(person);
        }
        mQuickAdapter.addAll(list);
    }


哦了,这样就实现列表展现了,纳尼?这样就搞定了?老子才不信呢!但我要说的是,这样就写完了,不需要再写一个专门的Adapter文件了,核心代码也就这四五行(在我们AS里面是,博客里展示可能换行了):

mQuickAdapter = new QuickAdapter<Person>(this, R.layout.single_item) {
            @Override
            protected void convert(BaseAdapterHelper helper, Person item) {
                helper.setText(R.id.tv_username, item.getUsername())
                        .setText(R.id.tv_age, item.getAge() + "岁")
                        .setText(R.id.tv_desc, item.getDesc());
                ImageLoader.getInstance().displayImage(item.getAvatar(), helper.getImageView(R.id.iv_avatar));
            }
        };


最后我们看下效果图:



和我们上面写的效果是一样一样滴!怎么样,给力吧,不用再为recyclerview写一大堆文件了吧,读者心里在想写到这里应该就完了吧?当然没有完,后面还有更强大的支持多种ViewType的,原版的支持listview、gridview的base-adapter-helper是不支持多种viewtype的,当然,网上已经有解决方案,具体看鸿洋base-adapter

2)、支持多个viewtype的quickadapter

代码和我们之前写的代码差不多,只不过加了一个MultiItemTypeSupport的支持,先看onCreate的代码:

RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));

        MultiItemTypeSupport<News> multiItemTypeSupport = new MultiItemTypeSupport<News>() {
            @Override
            public int getLayoutId(int viewType) {
                if (viewType == News.ITEM_TYPE_TEXT) {
                    return R.layout.multi_item_text;
                } else if (viewType == News.ITEM_TYPE_BUTTON) {
                    return R.layout.multi_item_button;
                } else if (viewType == News.ITEM_TYPE_IMAGE) {
                    return R.layout.multi_item_image;
                }
                //默认返回是文本
                return News.ITEM_TYPE_TEXT;
            }

            @Override
            public int getItemViewType(int position, News news) {
                return news.getItemType();
            }
        };

        mQuickAdapter = new QuickAdapter<News>(this, multiItemTypeSupport) {
            @Override
            protected void convert(final BaseAdapterHelper helper, News item) {
                switch (helper.getItemViewType()) {
                    case News.ITEM_TYPE_TEXT:
                        helper.setText(R.id.tv_text, item.getText());
                        break;
                    case News.ITEM_TYPE_BUTTON:
                        helper.setText(R.id.btn_click, item.getButton());
                        helper.setOnClickListener(R.id.btn_click, new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                Toast.makeText(MultiItemActivity.this, "你点击了按钮" + helper.getAdapterPosition(), Toast.LENGTH_SHORT).show();
                            }
                        });
                        break;
                    case News.ITEM_TYPE_IMAGE:
                        ImageLoader.getInstance().displayImage(item.getImage(), helper.getImageView(R.id.iv_image));
                        break;
                }
            }
        };

        recyclerView.setAdapter(mQuickAdapter);


再看初始化数据的代码:

private void initData() {
        List<News> list = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < 20; i++) {
            News news = new News();
            int index = random.nextInt(100) % 3;
            if (index == 0) {
                news.setText("新闻标题" + i);
                news.setItemType(News.ITEM_TYPE_TEXT);
            } else if (index == 1) {
                news.setButton("点击我" + i);
                news.setItemType(News.ITEM_TYPE_BUTTON);
            } else if (index == 2) {
                news.setImage("http://www.208206.com/uploads/allimg/150907/20224914K-0.jpg");
                news.setItemType(News.ITEM_TYPE_IMAGE);
            }
            list.add(news);
        }

        mQuickAdapter.addAll(list);
    }


这样就搞定了,看下最后的效果图:



5 . 总结原理

在项目里通过QuickAdapter能极大快速简化我们写的代码,而且用起来非常的方便快捷。在这里,原理我就不讲了,和原版的base-adapter-helper原理是一样的,还有我本来打算要把这个base-adapter-helper-recyclerview上传到jcenter上面去的,不过因为平时太忙了,等以后再弄吧,代码就四个java文件,别的木有



有需要的可以去我的github上去下载,github

地址为:base-adapter-helper-recyclerview,欢迎大家start和fork
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: