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="[email protected]" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >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="[email protected]" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >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="[email protected]" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >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