Android开发中经常需要使用Adapter。

传统方法是自定义一个Adapter并继承AndroidSDK内的BaseAdapter,

这种方式代码量大,耦合度高,灵活性差(各种监听事件需要对View单独写,或者自定义一个比较统一的方法);

而ZBLibrary中的BaseViewAdapter不仅预处理了通用方法(getCount,getItem等) 以及 Item复用逻辑,

而且将对Item的处理代码单独写在一个BaseView(提供了大量常用方法)的子类,

所以使用继承BaseViewAdapter的新方式能大幅精简代码,并且带来高灵活性和低耦合度。

比如这个界面

传统方式实现的CommonAdapter代码如下

 package com.example.quickadapter;

 import java.util.ArrayList;
import java.util.List; import zuo.biao.library.ui.WebViewActivity;
import zuo.biao.library.util.ImageLoaderUtil;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView; public class CommonAdapter extends BaseAdapter { private Activity context;
private List<User> list;
private LayoutInflater inflater;
public CommonAdapter(Activity context, List<User> list) {
this.context = context;
this.list = new ArrayList<>(list);
this.inflater = context.getLayoutInflater();
} @Override
public int getCount() {
return list.size();
} @Override
public User getItem(int position) {
return list.get(position);
} @Override
public long getItemId(int position) {
return position;
} public synchronized void refresh(List<User> list) {
if (list != null && list.size() > 0) {
this.list = new ArrayList<>(list);
}
notifyDataSetChanged();
} @Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = convertView == null ? null : (ViewHolder) convertView.getTag();
if (holder == null) {
convertView = inflater.inflate(R.layout.user_item, parent, false);
holder = new ViewHolder(); holder.ivUserItemHead = (ImageView) convertView.findViewById(R.id.ivUserItemHead);
holder.ivUserItemStar = (ImageView) convertView.findViewById(R.id.ivUserItemStar); holder.tvUserItemSex = (TextView) convertView.findViewById(R.id.tvUserItemSex); holder.tvUserItemName = (TextView) convertView.findViewById(R.id.tvUserItemName);
holder.tvUserItemId = (TextView) convertView.findViewById(R.id.tvUserItemId);
holder.tvUserItemNumber = (TextView) convertView.findViewById(R.id.tvUserItemNumber); convertView.setTag(holder);
} final User user = getItem(position); ImageLoaderUtil.loadImage(holder.ivUserItemHead, user.getHead(), ImageLoaderUtil.TYPE_OVAL);
holder.ivUserItemStar.setImageResource(user.getStarred() ? R.drawable.star_light : R.drawable.star); holder.tvUserItemSex.setBackgroundResource(user.getSex() == User.SEX_FEMAIL ? R.drawable.circle_pink : R.drawable.circle_blue);
holder.tvUserItemSex.setText(user.getSex() == User.SEX_FEMAIL ? "女" : "男");
holder.tvUserItemSex.setTextColor(context.getResources().getColor(user.getSex() == User.SEX_FEMAIL ? R.color.pink : R.color.blue)); holder.tvUserItemName.setText("" + user.getName());
holder.tvUserItemId.setText("ID:" + user.getId());
holder.tvUserItemNumber.setText("Phone:" + user.getPhone()); holder.ivUserItemHead.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
context.startActivity(WebViewActivity.createIntent(context, user.getName(), user.getHead()));
}
}); holder.ivUserItemStar.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
user.setStarred(! user.getStarred());
list.set(position, user);
refresh(null);
}
}); holder.tvUserItemSex.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
user.setSex(user.getSex() == User.SEX_FEMAIL ? User.SEX_MAIL : User.SEX_FEMAIL);
list.set(position, user);
refresh(null);
}
}); return convertView;
} class ViewHolder {
public ImageView ivUserItemHead;
public ImageView ivUserItemStar; public TextView tvUserItemSex; public TextView tvUserItemName;
public TextView tvUserItemId;
public TextView tvUserItemNumber;
}
}

继承BaseViewAdapter的新方式实现的QuickAdapter代码如下

 package com.example.quickadapter;

 import java.util.List;

 import zuo.biao.library.base.BaseView;
import zuo.biao.library.base.BaseViewAdapter;
import zuo.biao.library.ui.WebViewActivity;
import zuo.biao.library.util.ImageLoaderUtil;
import zuo.biao.library.util.StringUtil;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.res.Resources;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView; import com.example.quickadapter.QuickAdapter.UserView; public class QuickAdapter extends BaseViewAdapter<User, UserView> { public QuickAdapter(Activity context, List<User> list) {
super(context, list);
} @Override
public UserView createView(int position, View convertView, ViewGroup parent) {
return new UserView(context, resources);
} public class UserView extends BaseView<User> implements OnClickListener {
public UserView(Activity context, Resources resources) {
super(context, resources);
} public ImageView ivUserViewHead;
public ImageView ivUserViewStar; public TextView tvUserViewSex; public TextView tvUserViewName;
public TextView tvUserViewId;
public TextView tvUserViewNumber;
@SuppressLint("InflateParams")
@Override
public View createView(LayoutInflater inflater) {
convertView = inflater.inflate(R.layout.user_view, null); ivUserViewHead = findViewById(R.id.ivUserViewHead, this);
ivUserViewStar = findViewById(R.id.ivUserViewStar, this); tvUserViewSex = findViewById(R.id.tvUserViewSex, this); tvUserViewName = findViewById(R.id.tvUserViewName);
tvUserViewId = findViewById(R.id.tvUserViewId);
tvUserViewNumber = findViewById(R.id.tvUserViewNumber); return convertView;
} @Override
public void setView(User data){
if (data == null) {
return;
}
this.data = data; ImageLoaderUtil.loadImage(ivUserViewHead, data.getHead(), ImageLoaderUtil.TYPE_OVAL);
ivUserViewStar.setImageResource(data.getStarred() ? R.drawable.star_light : R.drawable.star); tvUserViewSex.setBackgroundResource(data.getSex() == User.SEX_FEMAIL ? R.drawable.circle_pink : R.drawable.circle_blue);
tvUserViewSex.setText(data.getSex() == User.SEX_FEMAIL ? "女" : "男");
tvUserViewSex.setTextColor(getColor(data.getSex() == User.SEX_FEMAIL ? R.color.pink : R.color.blue)); tvUserViewName.setText(StringUtil.getTrimedString(data.getName()));
tvUserViewId.setText("ID:" + data.getId());
tvUserViewNumber.setText("Phone:" + StringUtil.getNoBlankString(data.getPhone()));
} @Override
public void onClick(View v) {
if (data == null) {
return;
}
switch (v.getId()) {
case R.id.ivUserViewHead:
toActivity(WebViewActivity.createIntent(context, data.getName(), data.getHead()));
break;
case R.id.ivUserViewStar:
data.setStarred(! data.getStarred());
setView(data);
break;
case R.id.tvUserViewSex:
data.setSex(data.getSex() == User.SEX_FEMAIL ? User.SEX_MAIL : User.SEX_FEMAIL);
setView(data);
break;
default:
break;
}
}
}
}

看下ZBLibrary中的BaseView,里面有大量常用的 且 AndroidSDK内的BaseAdapter没有提供的 方法。

package zuo.biao.library.base;

import zuo.biao.library.util.CommonUtil;
import zuo.biao.library.util.Log;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.View.OnTouchListener; /**基础自定义View
* @author Lemon
* @param <T> 数据模型(model/JavaBean)类
* @see #onDestroy
* @use extends BaseView<T>, 具体参考.DemoView
*/
public abstract class BaseView<T> {
private static final String TAG = "BaseView"; /**
* 传入的Activity,可在子类直接使用
*/
protected Activity context;
protected Resources resources;
public BaseView(Activity context, Resources resources) {
this.context = context;
this.resources = resources == null ? context.getResources() : resources;
} /**数据改变回调接口
* (Object) getData() - 改变的数据
*/
public interface OnDataChangedListener {
void onDataChanged();
} public OnDataChangedListener onDataChangedListener;//数据改变回调监听类的实例
/**设置数据改变事件监听类
* @param l
*/
public void setOnDataChangedListener(OnDataChangedListener l) {
onDataChangedListener = l;
} public OnTouchListener onTouchListener;//接触View回调监听类的实例
/**设置接触View事件监听类
* @param l
*/
public void setOnTouchListener(OnTouchListener l) {
onTouchListener = l;
} public OnClickListener onClickListener;//点击View回调监听类的实例
/**设置点击View事件监听类
* @param l
*/
public void setOnClickListener(OnClickListener l) {
onClickListener = l;
} public OnLongClickListener onLongClickListener;//长按View回调监听类的实例
/**设置长按View事件监听类
* @param l
*/
public void setOnLongClickListener(OnLongClickListener l) {
onLongClickListener = l;
} /**
* 子类整个视图,可在子类直接使用
* @must createView方法内对其赋值且不能为null
*/
protected View convertView = null; /**通过id查找并获取控件,使用时不需要强转
* @param id
* @return
*/
@SuppressWarnings("unchecked")
public <V extends View> V findViewById(int id) {
return (V) convertView.findViewById(id);
}
/**通过id查找并获取控件,并setOnClickListener
* @param id
* @param l
* @return
*/
public <V extends View> V findViewById(int id, OnClickListener l) {
V v = findViewById(id);
v.setOnClickListener(l);
return v;
}
/**创建一个新的View
* @return
*/
public abstract View createView(@NonNull LayoutInflater inflater); /**获取convertView的宽度
* @warn 只能在createView后使用
* @return
*/
public int getWidth() {
return convertView.getWidth();
}
/**获取convertView的高度
* @warn 只能在createView后使用
* @return
*/
public int getHeight() {
return convertView.getHeight();
} /**
* data在列表中的位置
* @must 只使用setView(int position, T data)方法来设置position,保证position与data对应正确
*/
protected int position = 0;
/**获取data在列表中的位置
*/
public int getPosition() {
return position;
} protected T data = null;
/**获取数据
* @return
*/
public T getData() {
return data;
} /**设置并显示内容
* @warn 只能在createView后使用
* @param position - data在列表中的位置
* @param data - 传入的数据
*/
public void setView(int position, T data) {
this.position = position;
setView(data);
}
/**设置并显示内容
* @warn 只能在createView后使用
* @param data - 传入的数据
*/
public abstract void setView(T data); /**获取可见性
* @warn 只能在createView后使用
* @return 可见性 (View.VISIBLE, View.GONE, View.INVISIBLE);
*/
public int getVisibility() {
return convertView.getVisibility();
}
/**设置可见性
* @warn 只能在createView后使用
* @param visibility - 可见性 (View.VISIBLE, View.GONE, View.INVISIBLE);
*/
public void setVisibility(int visibility) {
convertView.setVisibility(visibility);
} /**设置背景
* @warn 只能在createView后使用
* @param resId
*/
public void setBackground(int resId) {
if (resId > 0 && convertView != null) {
try {
convertView.setBackgroundResource(resId);
} catch (Exception e) {
Log.e(TAG, "setBackground try { convertView.setBackgroundResource(resId);" +
" \n >> } catch (Exception e) { \n" + e.getMessage());
}
}
} //resources方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
public String getString(int id) {
return resources.getString(id);
}
public int getColor(int id) {
return resources.getColor(id);
}
public Drawable getDrawable(int id) {
return resources.getDrawable(id);
}
public float getDimension(int id) {
return resources.getDimension(id);
}
//resources方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> //show short toast 方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
/**快捷显示short toast方法,需要long toast就用 Toast.makeText(string, Toast.LENGTH_LONG).show(); ---不常用所以这个类里不写
* @param stringResId
*/
public void showShortToast(int stringResId) {
CommonUtil.showShortToast(context, stringResId);
}
/**快捷显示short toast方法,需要long toast就用 Toast.makeText(string, Toast.LENGTH_LONG).show(); ---不常用所以这个类里不写
* @param string
*/
public void showShortToast(String string) {
CommonUtil.showShortToast(context, string);
}
//show short toast 方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> //启动新Activity方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< /**打开新的Activity,向左滑入效果
* @param intent
*/
public void toActivity(final Intent intent) {
CommonUtil.toActivity(context, intent);
}
/**打开新的Activity
* @param intent
* @param showAnimation
*/
public void toActivity(final Intent intent, final boolean showAnimation) {
CommonUtil.toActivity(context, intent, showAnimation);
}
/**打开新的Activity,向左滑入效果
* @param intent
* @param requestCode
*/
public void toActivity(final Intent intent, final int requestCode) {
CommonUtil.toActivity(context, intent, requestCode);
}
/**打开新的Activity
* @param intent
* @param requestCode
* @param showAnimation
*/
public void toActivity(final Intent intent, final int requestCode, final boolean showAnimation) {
CommonUtil.toActivity(context, intent, requestCode, showAnimation);
}
//启动新Activity方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> /**销毁并回收内存,建议在对应的View占用大量内存时使用
* @warn 只能在UI线程中调用
*/
public void onDestroy() {
if (convertView != null) {
try {
convertView.destroyDrawingCache();
} catch (Exception e) {
Log.w(TAG, "onDestroy try { convertView.destroyDrawingCache();" +
" >> } catch (Exception e) {\n" + e.getMessage());
}
convertView = null;
} onDataChangedListener = null;
onTouchListener = null;
onClickListener = null;
onLongClickListener = null; data = null;
position = 0; context = null;
} }

本示例工程QuickAdapter

下载地址

http://files.cnblogs.com/files/tommylemon/QuickAdapter.zip

下载试用

QuickAdapter.apk

用到的开源库ZBLibrary(欢迎Star,欢迎Fork)

下载地址

https://github.com/TommyLemon/Android-ZBLibrary

下载试用

ZBLibraryDemoApp.apk

高灵活低耦合Adapter快速开发攻略的更多相关文章

  1. 面系那个对象开发原则.高内聚.低耦合+Python安装详细教程+print输出带颜色的方法

    面系那个对象开发原则.高内聚.低耦合 软件设计中通常用耦合度和内聚度作为衡量模块独立程度的标准.划分摸块的一个准则就是高内聚低耦合. 这是软件工程中的概念,是判断设计好坏的标准,主要是面向OO的设计, ...

  2. Java编码思想之什么是高内聚低耦合?

    分别描述的是模块内部特征,和模块外部引用关系. 内聚就是一个模块内各个元素彼此结合的紧密程度,高内聚就是一个模块内各个元素彼此结合的紧密程度高. 内聚是就其中任何一个模块的内部特征而言的. 耦合是就多 ...

  3. Office之什么是高内聚低耦合

    ---恢复内容开始--- 高内聚低耦合,是软件工程中的概念,是判断设计好坏的标准,主要是面向对象的设计,主要是看类的内聚性是否高,耦合度是否低. 粗劣的说就指的是:单独模块间有着强大的凝聚力,不同的模 ...

  4. Davinci DM6446开发攻略——DSP开发工程建立

    前段时间一直忙一个项目,同时在生活上时时提防和抵抗中国地沟油.国外核心转基因调和油.大豆油.色拉油.大米玉米.可怕的喂药鱼.药水泡农药喷无虫咬的青菜,所以没时间打理自己的博客,让开发攻略停顿了一段时间 ...

  5. TI Davinci DM6446开发攻略——根文件系统的裁剪和移植

    一.补充文件系统知识 Linux根文件系统是存放tool软件.lib文件.script(脚本).配置文件.其他特殊文件.自己开发的应用程序的地方.嵌入式linux的根文件系统rootfs就像windo ...

  6. Davinci DM6446开发攻略——linux-2.6.18移植

     TI DAVINCI 使用最新的内核是montavista linux-2.6.18,之前说过,国内很多公司,包括开发板的软件包,一直在使用montavista linux-2.6.10,这个版本准 ...

  7. DM6446开发攻略——u-boot-1.3.4移植(1)

    http://zjbintsystem.blog.51cto.com/964211/282387转载   UBOOT的版本更新速度比较快,截止今天,稳定正式的版本是u-boot-2009.11-rc2 ...

  8. TI Davinci DM6446开发攻略——开发环境搭建

    TI DAVINCI DM6446的开发环境搭建不像三星S3C2410,S3C2440,ATMEL的AT91SAM9260之类的单核ARM那么简单,因为DM6446还有DSP端的开发环境,以及双核之间 ...

  9. Davinci DM6446开发攻略——u-boot-1.3.4移植(1)

    UBOOT的版本更新速度比较快,截止今天,稳定正式的版本是u-boot-2009.11-rc2,而TI最新的EVM开发包里的UBOOT是1.2.0版本,国内很多公司还一直使用u-boot-1.1.4和 ...

随机推荐

  1. [转] python程序的调试方法

    qi09 原文 python程序的调试方法 本文讨论在没有方便的IDE工具可用的情况下,使用pdb调试python程序 源码例子 例如,有模拟税收计算的程序: #!/usr/bin/python de ...

  2. 《深入Java虚拟机学习笔记》- 第17章 异常

    <深入Java虚拟机学习笔记>- 第17章 异常

  3. python打包成exe(py2exe)

    对比了几个打包工具,发现py2exe更好用一点,一个命令就可以. 1.获取 http://prdownloads.sourceforge.net/py2exe 下载python版本对应的.直接下载然后 ...

  4. linux命令getopts

    一.getopts 简介 由于shell命令行的灵活性,自己编写代码判断时,复杂度会比较高.使用内部命令 getopts 可以很方便地处理命令行参数.一般格式为: getopts options va ...

  5. Java实现在访问者模式中使用反射

    集合类型在面向对象编程中很常用,这也带来一些代码相关的问题.比如,“怎么操作集合中不同类型的对象?” 一种做法就是遍历集合中的每个元素,然后根据它的类型而做具体的操作.这会很复杂,尤其当你不知道集合中 ...

  6. 教程-经典Delphi教程网

    有理想+志同道合的人+取长补短去协同工作=完美团队一流的项目 + 三流的执行者 = 垃圾项目三流的项目 + 一流的执行者 = 完美项目 自己公司网址:http://www.kaideruixin.ic ...

  7. 用Modelsim仿真QuartusII综合后网表时库的添加方法(转)

    这两天做综合后仿真,发现FPGA器件库又不会加了,无奈上网找方法.说起来不好意思,很早就接触Modelsim这个仿真软件了,可是没有好好琢磨.把这两天找的方法贴出来,再加上自己的理解,以后忘了可以上博 ...

  8. Spring Framework 5.0.0.M3中文文档 翻译记录 Part I. Spring框架概览2.3

    2.3 Usage scenarios 使用场景 The building blocks described previously make Spring a logical choice in ma ...

  9. iOS_城市定位

    技术点-利用CoreLoaction框架,实现城市定位功能. 原理: 利用苹果官方提供的CoreLocation框架实现城市定位的功能: 该框架主要包括两个比较有用的类:定位类CLLocationMa ...

  10. linux提权总结(外文)

    Before starting, I would like to point out - I'm no expert. As far as I know, there isn't a "ma ...