base-adapter-helper之recyclerview版本,支持多种viewtype布局
来源:互联网 发布:js floatparse 编辑:程序博客网 时间:2024/05/16 10:53
转载请标明出处:
http://blog.csdn.net/hanhailong726188/article/details/48277241
本文出自:海龙的博客
概述
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
- base-adapter-helper之recyclerview版本,支持多种viewtype布局
- RecyclerView.Adapter中的viewType
- RecyclerView Adapter Helper
- base-adapter-helper源码解析
- Recyclerview 多种 item 布局的通用 Adapter MultiItemAdapter
- 使用通用适配器Base-adapter-helper
- 对base-adapter-helper的简单分析
- Adapter实现多种布局
- adapter加载多种布局
- Android adapter设计模式二:使用base-adapter-helper
- RecyclerView添加多种布局
- RecyclerView中的多种布局
- RecyclerView中的多种布局
- RecyclerView中的多种布局
- RecyclerView展示多种布局
- RecyclerView多种item布局
- ListView的多种ViewType
- RecyclerView中的ViewType
- mapper.xml内容解析
- 1012--反射!!!
- 虚拟机nat模式连接
- 分享一个制作JQ插件方法的文章
- 文本视图(UITextView)
- base-adapter-helper之recyclerview版本,支持多种viewtype布局
- MessageBox
- rpm 命令
- Apache Tomcat 安装与调试
- 从TransactionTooLargeException谈到binder的内存管理
- 手把手教你写基于C++ Winsock的图片下载的网络爬虫
- Oracle Bi Publisher 报表的整合
- Unity3D 图集分割
- java测试小白来找大家交流了(Testlink的使用以及注意事项)