Android開發中經常需要使用Adapter。
傳統方法是自定義一個Adapter並繼承AndroidSDK內的BaseAdapter,
這種方式代碼量大,耦合度高,靈活性差(各種監聽事件需要對View單獨寫,或者自定義一個比較統一的方法);
而ZBLibrary中的BaseViewAdapter不僅預處理了通用方法(getCount,getItem等) 以及 Item複用邏輯,
而且將對Item的處理代碼單獨寫在一個BaseView(提供了大量常用方法)的子類,
所以使用繼承BaseViewAdapter的新方式能大幅精簡代碼,並且帶來高靈活性和低耦合度。
比如這個界面
傳統方式實現的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 @Override
103 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沒有提供的 方法。
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
下載試用
用到的開源庫ZBLibrary(歡迎Star,歡迎Fork)
下載地址(歡迎Star,歡迎Fork)
https://github.com/TommyLemon/Android-ZBLibrary
下載試用