万能适配器
来源:互联网 发布:深圳程序员培训机构 编辑:程序博客网 时间:2024/04/30 06:42
为何要使用万能适配器?
在安卓开发中,用到ListView和GridView的地方很多,如果你是开发一个简单点的APP还好,可能ListView和GridView的数量不会太多,我们只要去写几个BaseAdapter实现类就可以了。但如果有一天,你需要开发一个APP里面具有几十个ListView的子页面,此时的你该怎么办?每个ListView或GridView都去写一个适配的Adatper类吗?
这个时候就要想办法让自己减少很多工作量,避免做重复无意义劳动。
概念
就像上面说的我们每次都需要去继承一个BaseAdapter,然后实现里面的一大堆方法,而我们每次最关心的无非就是getView方法,其余的方法几乎都是相同代码。这里是不是就可以优化起来呢?在其次,我们在使用Adapter的时候,为了优化性能,常常会创建一个Holder。而Holder里面每次存放的都是View,对Holer的操作无非也就是初始化,绑定数据,复用。这里我们就抽取出两个类分别是CommonViewHolder和CommonAdapter来存放相同的东西。 好了,废话不多说,直接上代码。
第一步抽取出通用ViewHolder:
/** * 通用的ViewHolder * 照顾下初次使用SparseArray 其实它是Android推荐使用的一个优化容器,相当于一个Map<integer,View> * 目的是为了提供效率,其核心算法是折半查找,其用法和Map无两异。 * Created by lx_yoyo on 2016/8/10. */public class CommonViewHolder { private SparseArray<View> mViews; private View mConvertView; private CommonViewHolder(Context context, ViewGroup parent,int layoutId,int position) { this.mViews = new SparseArray<>(); mConvertView = LayoutInflater.from(context).inflate(layoutId,parent,false); mConvertView.setTag(this); } /** * 拿到一个ViewHolder对象 * @param context 上下文 * @param convertView 视图view * @param parent 容器 * @param layoutId 布局layoutID * @param position 当前索引 * @return */ public static CommonViewHolder get(Context context, View convertView, ViewGroup parent, int layoutId, int position) { if (convertView == null) { return new CommonViewHolder(context, parent, layoutId, position); } return (CommonViewHolder) convertView.getTag(); } /** * 通过控件的Id获取对于的控件,如果没有则加入views * @param viewId * @return */ public <T extends View> T getView(int viewId) { View view = mViews.get(viewId); if (view == null) { view = mConvertView.findViewById(viewId); mViews.put(viewId, view); } return (T) view; } public View getConvertView() { return mConvertView; }}
第二步抽取Adapter:
/** *通用Adapter * Created by lx_yoyo on 2016/8/10. */public abstract class CommonAdapter<T> extends BaseAdapter { protected LayoutInflater mInflater; protected Context mContext; protected List<T> mDatas; protected final int mItemLayoutId; public CommonAdapter(Context context, List<T> mDatas, int itemLayoutId) { this.mContext = context; this.mInflater = LayoutInflater.from(mContext); this.mDatas = mDatas; this.mItemLayoutId = itemLayoutId; } @Override public int getCount() { return mDatas.size(); } @Override public T getItem(int position) { return mDatas.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { final CommonViewHolder viewHolder = getViewHolder(position, convertView, parent); convert(viewHolder, getItem(position)); return viewHolder.getConvertView(); } public abstract void convert(CommonViewHolder helper, T t); private CommonViewHolder getViewHolder(int position, View convertView, ViewGroup parent) { return CommonViewHolder.get(mContext, convertView, parent, mItemLayoutId, position); }}
第三步就是Activity调用:
......private List<Bean> mDatas = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ListView listView = (ListvView)findViewById(R.id.Listview); listView.setAdapter(new CommonAdapter<Bean>(getApplicationContext(),mDatas,R.layout.list_item) { @Override public void convert(CommonViewHolder helper, Joke.ShowapiResBodyBean.ContentlistBean item) { //在这里就写item中的控件以及赋值 TextView titleText = helper.getView(R.id.text_title); titleText.setText(item.getTitle()); TextView contentText = helper.getView(R.id.text_content); contentText.setText(item.getText()); } } ); }......
以上就是一个万能适配器了,像CommonAdapter和CommonViewHolder基本上也不需要变动了,一劳永逸。
像上面简单控件赋值的话可以直接写在Activity里面,如比较复杂的item的话单独写个适配器,但不需要再
去继承BaseAdapter了,直接继承CommonAdapter配合CommonViewHolder就可以了。这样使代码量减少了很多。
当然以上代码还可以更简化一点,就是把这些ViewHolder.getView和setText,setImage等方法再一次封装,变成只传递控件Id和对应数据就够了,这样一来我们连类都不需要写了,直接用new对象去写个内部类实现就可以了。
代码如下:
/** *这里只写文字和图片的,如还需什么的自己去加就可以了 */public class CommonViewHolder { ...... /** * 为TextView设置字符串 * * @param viewId * @param text * @return */ public CommonViewHolder setText(int viewId, String text) { TextView view = getView(viewId); view.setText(text); return this; } /** * 为ImageView设置图片 * * @param viewId * @param drawableId * @return */ public CommonViewHolder setImageResource(int viewId, int drawableId) { ImageView view = getView(viewId); view.setImageResource(drawableId); return this; } /** * 为ImageView设置图片 * * @param viewId * @param drawableId * @return */ public CommonViewHolder setImageBitmap(int viewId, Bitmap bm) { ImageView view = getView(viewId); view.setImageBitmap(bm); return this; } /** * 为ImageView设置图片 * * @param viewId * @param drawableId * @return */ public CommonViewHolder setImageByUrl(int viewId, String url) { ImageLoader.getInstance(3, Type.LIFO).loadImage(url, (ImageView) getView(viewId)); return this; } ......}
现在在Activity只需要这么写:
......private List<Bean> mDatas = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ListView listView = (ListvView)findViewById(R.id.Listview); listView.setAdapter(new CommonAdapter<Bean>(getApplicationContext(),mDatas,R.layout.list_item) { @Override public void convert(CommonViewHolder helper, Bean item) { //在这里就写item中的控件以及赋值 helper.setText(R.id.id.text_title,item.getTitle()) .setText(R.id.text_content,item.getText); } } ); }......
到此,Android 打造万能的ListView GridView 适配器结束;
源码地址:点击下载万能适配器
谢谢!!!
- 万能适配器
- 万能适配器
- 万能适配器
- 万能适配器
- 万能适配器
- 万能的适配器 BaseAdapter
- 万能的适配器
- Android 万能适配器
- Android-打造万能适配器
- 万能适配器实战
- 万能ListView适配器
- 万能适配器MyBaseAdapter
- Android万能适配器
- Android中万能适配器
- 万能RecyclerView适配器
- 万能适配器 CommonAdapter
- Android 万能适配器
- Android--ListView--万能适配器
- opencv 保存mat矩阵的数据
- R语言十八讲(二)—Rstudio基础操作
- MVC5获取JSONResult数据并展示
- Android动画详解(二)属性动画完全解析(上)
- IIS 404 The page cannot be displayed because an internal server error has occurred
- 万能适配器
- MySQL中的时间类型转换timestamp
- HDU 2296 Ring (AC自动机+DP)
- eclipse下的快捷操作
- Android实现双击退出程序的效果
- Java Web 初级程序员 -第6天学习内容:类方法
- 1086. Tree Traversals Again (25)-PAT甲级真题
- CSS基础-选择器
- 15天用OFBiz做一个商城管理后台和店铺管理后台