1.ViewFinder的实现
package com.mycollege.util;
import java.lang.ref.WeakReference;
import android.content.Context;
import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* @{# ViewFinder.java Create on 2015-7-17 下午7:36:43
*
* class desc: view finder, 方便查找View。用户需要在使用时调用initContentView,
* 将Context和布局id传进来,然后使用findViewById来获取需要的view
* ,findViewById为泛型方法,返回的view则直接是你接收的类型,而不需要进行强制类型转换.比如,
* 以前我们在Activity中找一个TextView一般是这样 : TextView textView =
* (TextView)findViewById(viewId); 如果页面中的控件比较多,就会有很多的类型转换,而使用ViewFinder则免去了类型转换,
* 示例如下 : TextView textView = ViewFinder.findViewById(viewId);
*
* <p>
* Copyright: Copyright(c) 2015
* </p>
* @Version 1.0
* Tel 15211164134
* Name 潘传爱
* @Author <a href="15211164134@163.com">Hyca</a>
*
*/
public final class ViewFinder {
/**
*
*/
public static boolean DEBUG = false;
/**
* 每项的View的sub view Map
*/
private static SparseArray<WeakReference<View>> mViewMap = new SparseArray<WeakReference<View>>();
/**
* Root View的弱引用,
* 不会阻止View对象被释放。如果该mRootView没有被外部引用,那么在重新设置了rootView之后老的rootview会被释放.
*/
private static WeakReference<View> mRootView;
/**
* 设置Content View
*
* @param contentView 页面的Content View
*/
public static void initContentView(View contentView) {
if (contentView == null) {
throw new RuntimeException(
"ViewFinder init failed, mContentView == null.");
}
//
mRootView = new WeakReference<View>(contentView);
// 每次清除缓存的view id
mViewMap.clear();
}
/**
* 初始化ViewFinder, 实际上是获取到该页面的ContentView.
*
* @param context
* @param layoutId
*/
public static void initContentView(Context context, int layoutId) {
initContentView(context, null, layoutId);
}
/**
* @param context 上下文环境那个
* @param parent 父组件 ( ViewGroup )
* @param layoutId 布局id
*/
public static void initContentView(Context context, ViewGroup parent, int layoutId) {
if (context == null || layoutId <= 0) {
throw new RuntimeException(
"initContentView invalid params, context == null || layoutId == -1.");
}
// inflate the root view
View rootView = LayoutInflater.from(context).inflate(layoutId, parent, false);
//
initContentView(rootView);
}
/**
* 返回顶级视图
*
* @return
*/
public static View getContentView() {
return mRootView.get();
}
/**
* @param viewId
* @return
*/
@SuppressWarnings("unchecked")
public static <T extends View> T findViewById(int viewId) {
// 先从view map中查找,如果有的缓存的话直接使用,否则再从mContentView中找
View targetView = null;
// get from weak reference
WeakReference<View> viewWrf = mViewMap.get(viewId);
if (viewWrf != null) {
targetView = viewWrf.get();
}
if (targetView == null && mRootView != null && mRootView.get() != null) {
targetView = mRootView.get().findViewById(viewId);
mViewMap.put(viewId, new WeakReference<View>(targetView));
}
Log.d("", "### find view = " + targetView);
return targetView == null ? null : (T) targetView;
}
@SuppressWarnings("unchecked")
public static <T extends View> T findViewById(View rootView, int viewId) {
// 先从view map中查找,如果有的缓存的话直接使用,否则再从mContentView中找
View targetView = null;
// get from weak reference
if (rootView != null) {
targetView = rootView.findViewById(viewId);
}
Log.d("", "### find view = " + targetView);
return targetView == null ? null : (T) targetView;
}
/**
* 清理Views
*/
public static void clear() {
if (mRootView != null) {
mRootView.clear();
mRootView = null;
}
if (mViewMap != null) {
mViewMap.clear();
mViewMap = null;
}
}
}
2.CommonViewHolder的实现
package com.mycollege.util;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
/**
* @{# CommonViewHolder.java Create on 2015-7-17 下午7:35:59
*
* class desc: 这是一个通用的ViewHolder, 将会装载AbsListView子类的item View, 并且将item
* view中的子视图进行缓存和索引,使得用户能够方便的获取这些子view, 减少了代码重复。
* <p>
* Copyright: Copyright(c) 2015
* </p>
* @Version 1.0
* Tel 15211164134
* Name 潘传爱
* @Author <a href="15211164134@163.com">Hyca</a>
*
*/
public class CommonViewHolder {
/**
*
*/
private View mContentView;
/**
* 构造函数
*
* @param context Context
* @param layoutId ListView、GridView或者其他AbsListVew子类的 Item View的资源布局id
*/
protected CommonViewHolder(Context context, ViewGroup parent, int layoutId) {
mContentView = LayoutInflater.from(context).inflate(layoutId, parent, false);
mContentView.setTag(this);
}
/**
* 获取CommonViewHolder,当convertView为空的时候从布局xml装载item view,
* 并且将该CommonViewHolder设置为convertView的tag, 便于复用convertView.
*
* @param context Context
* @param convertView Item view
* @param layoutId 布局资源id, 例如R.layout.my_listview_item.
* @return 通用的CommonViewHolder实例
*/
public static CommonViewHolder getViewHolder(Context context, View convertView,
ViewGroup parent, int layoutId) {
context = (context == null && parent != null) ? parent.getContext() : context;
CommonViewHolder viewHolder = null;
if (convertView == null) {
viewHolder = new CommonViewHolder(context, parent, layoutId);
} else {
viewHolder = (CommonViewHolder) convertView.getTag();
}
// 将当前item view设置为ViewFinder要查找的root view, 这一步不能搞错,否则查找不到对象的view
// ViewFinder.initContentView(viewHolder.getContentView());
return viewHolder;
}
/**
* @return 当前项的convertView, 在构造函数中装载
*/
public View getContentView() {
return mContentView;
}
/**
* 为id为textViewId的TextView设置文本内容
*
* @param textViewId 视图id
* @param text 要设置的文本内容
*/
public void setTextForTextView(int textViewId, CharSequence text) {
TextView textView = ViewFinder.findViewById(mContentView, textViewId);
if (textView != null) {
textView.setText(text);
}
}
/**
* 为ImageView设置图片
*
* @param imageViewId ImageView的id, 例如R.id.my_imageview
* @param drawableId Drawable图片的id, 例如R.drawable.my_photo
*/
public void setImageForView(int imageViewId, int drawableId) {
ImageView imageView = ViewFinder.findViewById(mContentView, imageViewId);
if (imageView != null) {
imageView.setImageResource(drawableId);
}
}
/**
* 为ImageView设置图片
*
* @param imageViewId ImageView的id, 例如R.id.my_imageview
* @param bmp Bitmap图片
*/
public void setImageForView(int imageViewId, Bitmap bmp) {
ImageView imageView = ViewFinder.findViewById(mContentView, imageViewId);
if (imageView != null) {
imageView.setImageBitmap(bmp);
}
}
/**
* 为CheckBox设置是否选中
*
* @param checkViewId CheckBox的id
* @param isCheck 是否选中
*/
public void setCheckForCheckBox(int checkViewId, boolean isCheck) {
CheckBox checkBox = ViewFinder.findViewById(mContentView, checkViewId);
if (checkBox != null) {
checkBox.setChecked(isCheck);
}
}
/**
* @param viewId
* @param visibility
*/
public void setVisibility(int viewId, int visibility) {
View view = ViewFinder.findViewById(mContentView, viewId);
if (view != null) {
view.setVisibility(visibility);
}
}
/**
* @param viewId
* @param listener
*/
public void setOnClickListener(int viewId, OnClickListener listener) {
View view = ViewFinder.findViewById(mContentView, viewId);
if (view != null) {
view.setOnClickListener(listener);
}
}
/**
* @param viewId
* @param listener
*/
public void setOnTouchListener(int viewId, OnTouchListener listener) {
View view = ViewFinder.findViewById(mContentView, viewId);
if (view != null) {
view.setOnTouchListener(listener);
}
}
}
3.CommonAdapter实现
package com.mycollege.adapter;
import java.util.List;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import com.mycollege.util.CommonViewHolder;
/**
* @{# CommonAdapter.java Create on 2015-7-17 下午7:34:54
*
* class desc: 这是一个通用、抽象的适配器类,覆写了BaseAdapter的getCount, getItem, getItemId,
* getView方法,在getView方法中通过
* 通用的CommonViewHolder来对convertView的进行处理,并且缓存convertView中的其他View元素
* ,降低了ListView、GridView 等组件的Adapter和ViewHolder的代码量.
* 用户只需要在fillItemData函数中将第position位置里的数据填充到listview或者gridview的第position的view中即可
* ,具体使用实例参考文档.
* <p>
* Copyright: Copyright(c) 2015
* </p>
* @Version 1.0
* Tel 15211164134
* Name 潘传爱
* @Author <a href="15211164134@163.com">Hyca</a>
*
*/
public abstract class CommonAdapter<T> extends BaseAdapter {
/**
* Context
*/
Context mContext;
/**
* 要展示的数据列表
*/
List<T> mData;
/**
* 每一项的布局id,例如R.layout.my_listview_item.
*/
private int mItemLayoutId = -1;
/**
* @param context Context
* @param itemLayoutResId
* 每一项(适用于listview、gridview等AbsListView子类)的布局资源id,例如R.layout.
* my_listview_item.
* @param dataSource 数据源
*/
public CommonAdapter(Context context, int itemLayoutResId, List<T> dataSource) {
checkParams(context, itemLayoutResId, dataSource);
mContext = context;
mItemLayoutId = itemLayoutResId;
mData = dataSource;
}
/**
* 检查参数的有效性
*
* @param context
* @param itemLayoutResId
* @param dataSource
*/
private void checkParams(Context context, int itemLayoutResId, List<T> dataSource) {
if (context == null || itemLayoutResId < 0 || dataSource == null) {
throw new RuntimeException(
"context == null || itemLayoutResId < 0 || dataSource == null, please check your params");
}
}
/**
* 返回数据的总数
*/
@Override
public int getCount() {
return mData.size();
}
/**
* 返回position位置的数据
*/
@Override
public T getItem(int position) {
return mData.get(position);
}
/**
* item id, 返回position
*/
@Override
public long getItemId(int position) {
return position;
}
/**
* 返回position位置的view, 即listview、gridview的第postion个view
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// 获取ViewHolder
CommonViewHolder viewHolder = CommonViewHolder.getViewHolder(mContext, convertView, parent,
mItemLayoutId);
// 填充数据
fillItemData(viewHolder, position, getItem(position));
// 返回convertview
return viewHolder.getContentView();
}
/**
* 用户必须覆写该方法来讲数据填充到视图中
*
* @param viewHolder 通用的ViewHolder, 里面会装载listview,
* gridview等组件的每一项的视图,并且缓存其子view
* @param item 数据源的第position项数据
*/
protected abstract void fillItemData(CommonViewHolder viewHolder, int position, T item);
}
4.
万能适配器的使用代码(这里的参数你可以看一下源码)
CommonAdapter<AsAccountSecureEntity> adapter = new CommonAdapter<AsAccountSecureEntity>(this, R.layout.item_asaccountsecure, getListAsAccountSecureEntity()) {
@Override
protected void fillItemData(CommonViewHolder viewHolder, int position,
AsAccountSecureEntity item) {
viewHolder.setTextForTextView(R.id.tv_accountsecure, item.name);
viewHolder.setTextForTextView(R.id.tv_accountsecurevalue, item.value);
//viewHolder.setImageForView(R.id.iv_accountsecure, item.drawableLeft);
//viewHolder.setImageForView(R.id.iv_accountsecureclick, item.drawableRight);
}
};
源码下载地址:http://download.csdn.net/detail/pcaxb/9037975