Android开发中经常需要使用Adapter。
传统方法是自定义一个Adapter并继承AndroidSDK内的BaseAdapter,
这种方式代码量大,耦合度高,灵活性差(各种监听事件需要对View单独写,或者自定义一个比较统一的方法);
而ZBLibrary中的BaseViewAdapter不仅预处理了通用方法(getCount,getItem等) 以及 Item复用逻辑,
而且将对Item的处理代码单独写在一个BaseView(提供了大量常用方法)的子类,
所以使用继承BaseViewAdapter的新方式能大幅精简代码,并且带来高灵活性和低耦合度。
比如这个界面
images/loading.gif' data-original="http://images2015.cnblogs.com/blog/660067/201606/660067-20160626211719172-598164985.png" />
传统方式实现的CommonAdapter代码如下
1 package com.example.quickadapter; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import zuo.biao.library.ui.WebViewActivity; 7 import zuo.biao.library.util.ImageLoaderUtil; 8 import android.app.Activity; 9 import android.view.LayoutInflater; 10 import android.view.View; 11 import android.view.View.OnClickListener; 12 import android.view.ViewGroup; 13 import android.widget.BaseAdapter; 14 import android.widget.ImageView; 15 import android.widget.TextView; 16 17 public class CommonAdapter extends BaseAdapter { 18 19 private Activity context; 20 private List<User> list; 21 private LayoutInflater inflater; 22 public CommonAdapter(Activity context, List<User> list) { 23 this.context = context; 24 this.list = new ArrayList<>(list); 25 this.inflater = context.getLayoutInflater(); 26 } 27 28 @Override 29 public int getCount() { 30 return list.size(); 31 } 32 33 @Override 34 public User getItem(int position) { 35 return list.get(position); 36 } 37 38 @Override 39 public long getItemId(int position) { 40 return position; 41 } 42 43 public synchronized void refresh(List<User> list) { 44 if (list != null && list.size() > 0) { 45 this.list = new ArrayList<>(list); 46 } 47 notifyDataSetChanged(); 48 } 49 50 @Override 51 public View getView(final int position, View convertView, ViewGroup parent) { 52 ViewHolder holder = convertView == null ? null : (ViewHolder) convertView.getTag(); 53 if (holder == null) { 54 convertView = inflater.inflate(R.layout.user_item, parent, false); 55 holder = new ViewHolder(); 56 57 holder.ivUserItemHead = (ImageView) convertView.findViewById(R.id.ivUserItemHead); 58 holder.ivUserItemStar = (ImageView) convertView.findViewById(R.id.ivUserItemStar); 59 60 holder.tvUserItemSex = (TextView) convertView.findViewById(R.id.tvUserItemSex); 61 62 holder.tvUserItemName = (TextView) convertView.findViewById(R.id.tvUserItemName); 63 holder.tvUserItemId = (TextView) convertView.findViewById(R.id.tvUserItemId); 64 holder.tvUserItemNumber = (TextView) convertView.findViewById(R.id.tvUserItemNumber); 65 66 convertView.setTag(holder); 67 } 68 69 final User user = getItem(position); 70 71 ImageLoaderUtil.loadImage(holder.ivUserItemHead, user.getHead(), ImageLoaderUtil.TYPE_OVAL); 72 holder.ivUserItemStar.setImageResource(user.getStarred() ? R.drawable.star_light : R.drawable.star); 73 74 holder.tvUserItemSex.setBackgroundResource(user.getSex() == User.SEX_FEMAIL ? R.drawable.circle_pink : R.drawable.circle_blue); 75 holder.tvUserItemSex.setText(user.getSex() == User.SEX_FEMAIL ? "女" : "男"); 76 holder.tvUserItemSex.setTextColor(context.getResources().getColor(user.getSex() == User.SEX_FEMAIL ? R.color.pink : R.color.blue)); 77 78 holder.tvUserItemName.setText("" + user.getName()); 79 holder.tvUserItemId.setText("ID:" + user.getId()); 80 holder.tvUserItemNumber.setText("Phone:" + user.getPhone()); 81 82 holder.ivUserItemHead.setOnClickListener(new OnClickListener() { 83 84 @Override 85 public void onClick(View v) { 86 context.startActivity(WebViewActivity.createIntent(context, user.getName(), user.getHead())); 87 } 88 }); 89 90 holder.ivUserItemStar.setOnClickListener(new OnClickListener() { 91 92 @Override 93 public void onClick(View v) { 94 user.setStarred(! user.getStarred()); 95 list.set(position, user); 96 refresh(null); 97 } 98 }); 99 100 holder.tvUserItemSex.setOnClickListener(new OnClickListener() {101 102 @Override103 public void onClick(View v) {104 user.setSex(user.getSex() == User.SEX_FEMAIL ? User.SEX_MAIL : User.SEX_FEMAIL);105 list.set(position, user);106 refresh(null);107 }108 });109 110 return convertView;111 }112 113 class ViewHolder {114 public ImageView ivUserItemHead;115 public ImageView ivUserItemStar;116 117 public TextView tvUserItemSex;118 119 public TextView tvUserItemName;120 public TextView tvUserItemId;121 public TextView tvUserItemNumber;122 }123 }
继承BaseViewAdapter的新方式实现的QuickAdapter代码如下
1 package com.example.quickadapter; 2 3 import java.util.List; 4 5 import zuo.biao.library.base.BaseView; 6 import zuo.biao.library.base.BaseViewAdapter; 7 import zuo.biao.library.ui.WebViewActivity; 8 import zuo.biao.library.util.ImageLoaderUtil; 9 import zuo.biao.library.util.StringUtil; 10 import android.annotation.SuppressLint; 11 import android.app.Activity; 12 import android.content.res.Resources; 13 import android.view.LayoutInflater; 14 import android.view.View; 15 import android.view.View.OnClickListener; 16 import android.view.ViewGroup; 17 import android.widget.ImageView; 18 import android.widget.TextView; 19 20 import com.example.quickadapter.QuickAdapter.UserView; 21 22 public class QuickAdapter extends BaseViewAdapter<User, UserView> { 23 24 public QuickAdapter(Activity context, List<User> list) { 25 super(context, list); 26 } 27 28 @Override 29 public UserView createView(int position, View convertView, ViewGroup parent) { 30 return new UserView(context, resources); 31 } 32 33 public class UserView extends BaseView<User> implements OnClickListener { 34 public UserView(Activity context, Resources resources) { 35 super(context, resources); 36 } 37 38 public ImageView ivUserViewHead; 39 public ImageView ivUserViewStar; 40 41 public TextView tvUserViewSex; 42 43 public TextView tvUserViewName; 44 public TextView tvUserViewId; 45 public TextView tvUserViewNumber; 46 @SuppressLint("InflateParams") 47 @Override 48 public View createView(LayoutInflater inflater) { 49 convertView = inflater.inflate(R.layout.user_view, null); 50 51 ivUserViewHead = findViewById(R.id.ivUserViewHead, this); 52 ivUserViewStar = findViewById(R.id.ivUserViewStar, this); 53 54 tvUserViewSex = findViewById(R.id.tvUserViewSex, this); 55 56 tvUserViewName = findViewById(R.id.tvUserViewName); 57 tvUserViewId = findViewById(R.id.tvUserViewId); 58 tvUserViewNumber = findViewById(R.id.tvUserViewNumber); 59 60 return convertView; 61 } 62 63 @Override 64 public void setView(User data){ 65 if (data == null) { 66 return; 67 } 68 this.data = data; 69 70 ImageLoaderUtil.loadImage(ivUserViewHead, data.getHead(), ImageLoaderUtil.TYPE_OVAL); 71 ivUserViewStar.setImageResource(data.getStarred() ? R.drawable.star_light : R.drawable.star); 72 73 tvUserViewSex.setBackgroundResource(data.getSex() == User.SEX_FEMAIL ? R.drawable.circle_pink : R.drawable.circle_blue); 74 tvUserViewSex.setText(data.getSex() == User.SEX_FEMAIL ? "女" : "男"); 75 tvUserViewSex.setTextColor(getColor(data.getSex() == User.SEX_FEMAIL ? R.color.pink : R.color.blue)); 76 77 tvUserViewName.setText(StringUtil.getTrimedString(data.getName())); 78 tvUserViewId.setText("ID:" + data.getId()); 79 tvUserViewNumber.setText("Phone:" + StringUtil.getNoBlankString(data.getPhone())); 80 } 81 82 @Override 83 public void onClick(View v) { 84 if (data == null) { 85 return; 86 } 87 switch (v.getId()) { 88 case R.id.ivUserViewHead: 89 toActivity(WebViewActivity.createIntent(context, data.getName(), data.getHead())); 90 break; 91 case R.id.ivUserViewStar: 92 data.setStarred(! data.getStarred()); 93 setView(data); 94 break; 95 case R.id.tvUserViewSex: 96 data.setSex(data.getSex() == User.SEX_FEMAIL ? User.SEX_MAIL : User.SEX_FEMAIL); 97 setView(data); 98 break; 99 default:100 break;101 } 102 }103 }104 }
看下ZBLibrary中的BaseView,里面有大量常用的 且 AndroidSDK内的BaseAdapter没有提供的 方法。
1 package zuo.biao.library.base; 2 3 import zuo.biao.library.util.CommonUtil; 4 import zuo.biao.library.util.Log; 5 import android.app.Activity; 6 import android.content.Intent; 7 import android.content.res.Resources; 8 import android.graphics.drawable.Drawable; 9 import android.support.annotation.NonNull; 10 import android.view.LayoutInflater; 11 import android.view.View; 12 import android.view.View.OnClickListener; 13 import android.view.View.OnLongClickListener; 14 import android.view.View.OnTouchListener; 15 16 /**基础自定义View 17 * @author Lemon 18 * @param <T> 数据模型(model/JavaBean)类 19 * @see #onDestroy 20 * @use extends BaseView<T>, 具体参考.DemoView 21 */ 22 public abstract class BaseView<T> { 23 private static final String TAG = "BaseView"; 24 25 /** 26 * 传入的Activity,可在子类直接使用 27 */ 28 protected Activity context; 29 protected Resources resources; 30 public BaseView(Activity context, Resources resources) { 31 this.context = context; 32 this.resources = resources == null ? context.getResources() : resources; 33 } 34 35 /**数据改变回调接口 36 * (Object) getData() - 改变的数据 37 */ 38 public interface OnDataChangedListener { 39 void onDataChanged(); 40 } 41 42 public OnDataChangedListener onDataChangedListener;//数据改变回调监听类的实例 43 /**设置数据改变事件监听类 44 * @param l 45 */ 46 public void setOnDataChangedListener(OnDataChangedListener l) { 47 onDataChangedListener = l; 48 } 49 50 public OnTouchListener onTouchListener;//接触View回调监听类的实例 51 /**设置接触View事件监听类 52 * @param l 53 */ 54 public void setOnTouchListener(OnTouchListener l) { 55 onTouchListener = l; 56 } 57 58 public OnClickListener onClickListener;//点击View回调监听类的实例 59 /**设置点击View事件监听类 60 * @param l 61 */ 62 public void setOnClickListener(OnClickListener l) { 63 onClickListener = l; 64 } 65 66 public OnLongClickListener onLongClickListener;//长按View回调监听类的实例 67 /**设置长按View事件监听类 68 * @param l 69 */ 70 public void setOnLongClickListener(OnLongClickListener l) { 71 onLongClickListener = l; 72 } 73 74 75 76 /** 77 * 子类整个视图,可在子类直接使用 78 * @must createView方法内对其赋值且不能为null 79 */ 80 protected View convertView = null; 81 82 /**通过id查找并获取控件,使用时不需要强转 83 * @param id 84 * @return 85 */ 86 @SuppressWarnings("unchecked") 87 public <V extends View> V findViewById(int id) { 88 return (V) convertView.findViewById(id); 89 } 90 /**通过id查找并获取控件,并setOnClickListener 91 * @param id 92 * @param l 93 * @return 94 */ 95 public <V extends View> V findViewById(int id, OnClickListener l) { 96 V v = findViewById(id); 97 v.setOnClickListener(l); 98 return v; 99 }100 /**创建一个新的View101 * @return102 */103 public abstract View createView(@NonNull LayoutInflater inflater);104 105 /**获取convertView的宽度106 * @warn 只能在createView后使用107 * @return108 */109 public int getWidth() {110 return convertView.getWidth();111 }112 /**获取convertView的高度113 * @warn 只能在createView后使用114 * @return115 */116 public int getHeight() {117 return convertView.getHeight();118 }119 120 /**121 * data在列表中的位置122 * @must 只使用setView(int position, T data)方法来设置position,保证position与data对应正确123 */124 protected int position = 0;125 /**获取data在列表中的位置126 */127 public int getPosition() {128 return position;129 }130 131 protected T data = null;132 /**获取数据133 * @return134 */135 public T getData() {136 return data;137 }138 139 /**设置并显示内容140 * @warn 只能在createView后使用141 * @param position - data在列表中的位置142 * @param data - 传入的数据143 */144 public void setView(int position, T data) {145 this.position = position;146 setView(data);147 }148 /**设置并显示内容149 * @warn 只能在createView后使用150 * @param data - 传入的数据151 */152 public abstract void setView(T data);153 154 /**获取可见性155 * @warn 只能在createView后使用156 * @return 可见性 (View.VISIBLE, View.GONE, View.INVISIBLE);157 */158 public int getVisibility() {159 return convertView.getVisibility();160 }161 /**设置可见性162 * @warn 只能在createView后使用163 * @param visibility - 可见性 (View.VISIBLE, View.GONE, View.INVISIBLE);164 */165 public void setVisibility(int visibility) {166 convertView.setVisibility(visibility);167 }168 169 170 /**设置背景171 * @warn 只能在createView后使用172 * @param resId173 */174 public void setBackground(int resId) {175 if (resId > 0 && convertView != null) {176 try {177 convertView.setBackgroundResource(resId);178 } catch (Exception e) {179 Log.e(TAG, "setBackground try { convertView.setBackgroundResource(resId);" +180 " \n >> } catch (Exception e) { \n" + e.getMessage());181 }182 }183 }184 185 186 //resources方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<187 public String getString(int id) {188 return resources.getString(id);189 }190 public int getColor(int id) {191 return resources.getColor(id);192 }193 public Drawable getDrawable(int id) {194 return resources.getDrawable(id);195 }196 public float getDimension(int id) {197 return resources.getDimension(id);198 }199 //resources方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>200 201 202 //show short toast 方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<203 /**快捷显示short toast方法,需要long toast就用 Toast.makeText(string, Toast.LENGTH_LONG).show(); ---不常用所以这个类里不写204 * @param stringResId205 */206 public void showShortToast(int stringResId) {207 CommonUtil.showShortToast(context, stringResId);208 }209 /**快捷显示short toast方法,需要long toast就用 Toast.makeText(string, Toast.LENGTH_LONG).show(); ---不常用所以这个类里不写210 * @param string211 */212 public void showShortToast(String string) {213 CommonUtil.showShortToast(context, string);214 }215 //show short toast 方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>216 217 218 //启动新Activity方法<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<219 220 /**打开新的Activity,向左滑入效果221 * @param intent222 */223 public void toActivity(final Intent intent) {224 CommonUtil.toActivity(context, intent);225 }226 /**打开新的Activity227 * @param intent228 * @param showAnimation229 */230 public void toActivity(final Intent intent, final boolean showAnimation) {231 CommonUtil.toActivity(context, intent, showAnimation);232 }233 /**打开新的Activity,向左滑入效果234 * @param intent235 * @param requestCode236 */237 public void toActivity(final Intent intent, final int requestCode) {238 CommonUtil.toActivity(context, intent, requestCode);239 }240 /**打开新的Activity241 * @param intent242 * @param requestCode243 * @param showAnimation244 */245 public void toActivity(final Intent intent, final int requestCode, final boolean showAnimation) {246 CommonUtil.toActivity(context, intent, requestCode, showAnimation);247 }248 //启动新Activity方法>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>249 250 /**销毁并回收内存,建议在对应的View占用大量内存时使用251 * @warn 只能在UI线程中调用252 */253 public void onDestroy() {254 if (convertView != null) {255 try {256 convertView.destroyDrawingCache();257 } catch (Exception e) {258 Log.w(TAG, "onDestroy try { convertView.destroyDrawingCache();" +259 " >> } catch (Exception e) {\n" + e.getMessage());260 }261 convertView = null;262 }263 264 onDataChangedListener = null;265 onTouchListener = null;266 onClickListener = null;267 onLongClickListener = null;268 269 data = null;270 position = 0;271 272 context = null;273 }274 275 }
本示例工程QuickAdapter
下载地址
http://files.cnblogs.com/files/tommylemon/QuickAdapter.zip
下载试用
QuickAdapter.apk
用到的开源库ZBLibrary(欢迎Star,欢迎Fork)
下载地址
https://github.com/TommyLemon/Android-ZBLibrary
下载试用
ZBLibraryDemoApp.apk
原标题:高灵活低耦合Adapter快速开发攻略
关键词: