日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

Android中适用于ListView、GridView等组件的通用Adapter

發(fā)布時(shí)間:2024/4/14 Android 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android中适用于ListView、GridView等组件的通用Adapter 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

? ? 今天隨便逛逛CSDN,看到主頁(yè)上推薦了一篇文章Android 高速開(kāi)發(fā)系列 打造萬(wàn)能的ListView GridView 適配器,剛好這兩天寫項(xiàng)目自己也封裝了相似的CommonAdapter,曾經(jīng)也在github上看到過(guò)這種庫(kù),于是自己也把自己的代碼再次整理出來(lái)與大家分享,也希望可以在CSDN這個(gè)平臺(tái)上學(xué)到很多其它的東西,以下就一起來(lái)看看吧。

? ? 平時(shí)我們?cè)陧?xiàng)目中使用到ListView和GridView組件都是都會(huì)用到Adapter,比較多的情況是繼承自BaseAdapter,然后實(shí)現(xiàn)getCount、getView等方法,再使用ViewHolder來(lái)提高一下效率.我們看以下一個(gè)簡(jiǎn)單的樣例 :

ListView布局文件

fragment_main.xml :

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="com.example.push_demo_1.MainActivity$PlaceholderFragment" ><ListViewandroid:id="@+id/my_listview"android:layout_width="match_parent"android:layout_height="match_parent" /></RelativeLayout>

ListView子項(xiàng)的布局文件

listview_item_layout.xml :

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal" ><ImageViewandroid:id="@+id/my_imageview"android:layout_width="64dp"android:layout_height="64dp"android:contentDescription="@string/app_name" /><TextViewandroid:id="@+id/my_textview"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="20dp"android:textSize="18sp" /></LinearLayout>

曾經(jīng)我們要寫下的Adapter代碼

public class NormalAdapter extends BaseAdapter {Context mContext;LayoutInflater mInflater;List<ListViewItem> mDataList;/*** @param context* @param data*/public NormalAdapter(Context context, List<ListViewItem> data) {mContext = context;mInflater = LayoutInflater.from(context);mDataList = data;}@Overridepublic int getCount() {return mDataList.size();}@Overridepublic ListViewItem getItem(int position) {return mDataList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder viewHolder = null;if (convertView == null) {convertView = mInflater.inflate(R.layout.listview_item_layout, null, false);viewHolder = new ViewHolder();viewHolder.mImageView = (ImageView) convertView.findViewById(R.id.my_imageview);viewHolder.mTextView = (TextView) convertView.findViewById(R.id.my_textview);convertView.setTag(viewHolder);} else {viewHolder = (ViewHolder) convertView.getTag();}viewHolder.mImageView.setImageResource(getItem(position).mDrawableId);viewHolder.mTextView.setText(getItem(position).mText);return convertView;}/*** ViewHolder* * @author mrsimple*/static class ViewHolder {ImageView mImageView;TextView mTextView;}}

? ? 然而寫過(guò)多遍以后我們發(fā)現(xiàn)我們總是反復(fù)地在寫這些getCount、getItem、getView方法以及ViewHolder,導(dǎo)致了非常多反復(fù)工作,而且及其無(wú)聊,于是我把這些反復(fù)工作抽象起來(lái)(曾經(jīng)也有在github上看到這種通用Adapter實(shí)現(xiàn)),整理一下也便于自己使用,也是自己學(xué)習(xí)的一個(gè)過(guò)程。以下我們看看使用CommonAdapter后我們做與上面相同的工作須要怎么寫。

使用CommonAdapter后要寫的代碼

CommonAdapter<ListViewItem> listAdapter = new CommonAdapter<ListViewItem>(getActivity(),R.layout.listview_item_layout, mockListViewItems()) {@Overrideprotected void fillItemData(CommonViewHolder viewHolder, ListViewItem item) {// 設(shè)置圖片viewHolder.setImageForView(R.id.my_imageview, item.mDrawableId);// 設(shè)置textviewHolder.setTextForTextView(R.id.my_textview, item.mText);}}
當(dāng)中mockListViewImtes是準(zhǔn)備了一些數(shù)據(jù), 代碼例如以下 :? /*** 模擬一些數(shù)據(jù)* * @return*/private List<ListViewItem> mockListViewItems() {List<ListViewItem> dataItems = new ArrayList<ListViewItem>();dataItems.add(new ListViewItem(R.drawable.girl_96, "girl_96.png"));dataItems.add(new ListViewItem(R.drawable.fire_96, "fire_96.png"));dataItems.add(new ListViewItem(R.drawable.grimace_96, "grimace_96.png"));dataItems.add(new ListViewItem(R.drawable.laugh_96, "laugh_96.png"));return dataItems;}

可以看到,我們的代碼量降低了非常多,假設(shè)一個(gè)項(xiàng)目中有好幾個(gè)ListView、GridView等組件,我們就不須要反復(fù)做那么多無(wú)聊的工作了。我們看看效果圖 :?


CommonAdapter實(shí)現(xiàn)

/**** created by Mr.Simple, Aug 28, 201412:26:52 PM.* Copyright (c) 2014, hehonghui@umeng.com All Rights Reserved.** #####################################################* # #* # _oo0oo_ # * # o8888888o #* # 88" . "88 #* # (| -_- |) #* # 0\ = /0 # * # ___/`---'\___ #* # .' \\| |# '. #* # / \\||| : |||# \ #* # / _||||| -:- |||||- \ #* # | | \\\ - #/ | | #* # | \_| ''\---/'' |_/ | #* # \ .-\__ '-' ___/-. / #* # ___'. .' /--.--\ `. .'___ #* # ."" '< `.___\_<|>_/___.' >' "". #* # | | : `- \`.;`\ _ /`;.`/ - ` : | | #* # \ \ `_. \_ __\ /__ _/ .-` / / #* # =====`-.____`.___ \_____/___.-`___.-'===== #* # `=---=' #* # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #* # #* # 佛祖保佑 永無(wú)BUG #* # #* #####################################################*/package com.uit.commons;import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter;import java.util.List;/*** 這是一個(gè)通用、抽象的適配器類,覆寫了BaseAdapter的getCount, getItem, getItemId,* getView方法,在getView方法中通過(guò)* 通用的CommonViewHolder來(lái)對(duì)convertView的進(jìn)行處理,而且緩存convertView中的其它View元素* ,降低了ListView、GridView 等組件的Adapter和ViewHolder的代碼量.* 用戶僅僅須要在fillItemData函數(shù)中將第position位置里的數(shù)據(jù)填充到listview或者gridview的第position的view中就可以* ,詳細(xì)使用實(shí)例參考文檔.* * @author mrsimple* @param <T> 數(shù)據(jù)源的類型*/ public abstract class CommonAdapter<T> extends BaseAdapter {/*** Context*/Context mContext;/*** 要展示的數(shù)據(jù)列表*/List<T> mData;/*** 每一項(xiàng)的布局id,比如R.layout.my_listview_item.*/private int mItemLayoutId = -1;/*** @param context Context* @param itemLayoutResId* 每一項(xiàng)(適用于listview、gridview等AbsListView子類)的布局資源id,比如R.layout.* my_listview_item.* @param dataSource 數(shù)據(jù)源*/public CommonAdapter(Context context, int itemLayoutResId, List<T> dataSource) {checkParams(context, itemLayoutResId, dataSource);mContext = context;mItemLayoutId = itemLayoutResId;mData = dataSource;}/*** 檢查參數(shù)的有效性* * @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");}}/*** 返回?cái)?shù)據(jù)的總數(shù)*/@Overridepublic int getCount() {return mData.size();}/*** 返回position位置的數(shù)據(jù)*/@Overridepublic T getItem(int position) {return mData.get(position);}/*** item id, 返回position*/@Overridepublic long getItemId(int position) {return position;}/*** 返回position位置的view, 即listview、gridview的第postion個(gè)view*/@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// 獲取ViewHolderCommonViewHolder viewHolder = CommonViewHolder.getViewHolder(mContext, convertView,mItemLayoutId);// 填充數(shù)據(jù)fillItemData(viewHolder, getItem(position));// 返回convertviewreturn viewHolder.getConvertView();}/*** 用戶必須覆寫該方法來(lái)講數(shù)據(jù)填充到視圖中* * @param viewHolder 通用的ViewHolder, 里面會(huì)裝載listview,* gridview等組件的每一項(xiàng)的視圖,而且緩存其子view* @param item 數(shù)據(jù)源的第position項(xiàng)數(shù)據(jù)*/protected abstract void fillItemData(CommonViewHolder viewHolder, T item);}

CommonViewHolder實(shí)現(xiàn)

/**** created by Mr.Simple, Aug 28, 201412:32:45 PM.* Copyright (c) 2014, hehonghui@umeng.com All Rights Reserved.** #####################################################* # #* # _oo0oo_ # * # o8888888o #* # 88" . "88 #* # (| -_- |) #* # 0\ = /0 # * # ___/`---'\___ #* # .' \\| |# '. #* # / \\||| : |||# \ #* # / _||||| -:- |||||- \ #* # | | \\\ - #/ | | #* # | \_| ''\---/'' |_/ | #* # \ .-\__ '-' ___/-. / #* # ___'. .' /--.--\ `. .'___ #* # ."" '< `.___\_<|>_/___.' >' "". #* # | | : `- \`.;`\ _ /`;.`/ - ` : | | #* # \ \ `_. \_ __\ /__ _/ .-` / / #* # =====`-.____`.___ \_____/___.-`___.-'===== #* # `=---=' #* # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #* # #* # 佛祖保佑 永無(wú)BUG #* # #* #####################################################*/package com.uit.commons;import android.content.Context; import android.graphics.Bitmap; import android.view.View; import android.widget.CheckBox; import android.widget.ImageView; import android.widget.TextView;import com.uit.commons.utils.ViewFinder;/*** 這是一個(gè)通用的ViewHolder, 將會(huì)裝載AbsListView子類的item View, 而且將item* view中的子視圖進(jìn)行緩存和索引,使得用戶可以方便的獲取這些子view, 降低了代碼反復(fù)。* * @author mrsimple*/ public class CommonViewHolder {/*** 構(gòu)造函數(shù)* * @param context Context* @param layoutId ListView、GridView或者其它AbsListVew子類的 Item View的資源布局id*/protected CommonViewHolder(Context context, int layoutId) {// 初始化布局, 裝載ContentViewViewFinder.initContentView(context, layoutId);// 將ViewHolder存儲(chǔ)在ContentView的tag中ViewFinder.getContentView().setTag(this);}/*** 獲取CommonViewHolder,當(dāng)convertView為空的時(shí)候從布局xml裝載item view,* 而且將該CommonViewHolder設(shè)置為convertView的tag, 便于復(fù)用convertView.* * @param context Context* @param convertView Item view* @param layoutId 布局資源id, 比如R.layout.my_listview_item.* @return 通用的CommonViewHolder實(shí)例*/public static CommonViewHolder getViewHolder(Context context, View convertView, int layoutId) {if (convertView == null) {return new CommonViewHolder(context, layoutId);}return (CommonViewHolder) convertView.getTag();}/*** @return 當(dāng)前項(xiàng)的convertView, 在構(gòu)造函數(shù)中裝載*/public View getConvertView() {return ViewFinder.getContentView();}/*** 為id為textViewId的TextView設(shè)置文本內(nèi)容* * @param textViewId 視圖id* @param text 要設(shè)置的文本內(nèi)容*/public void setTextForTextView(int textViewId, CharSequence text) {TextView textView = ViewFinder.findViewById(textViewId);if (textView != null) {textView.setText(text);}}/*** 為ImageView設(shè)置圖片* * @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(imageViewId);if (imageView != null) {imageView.setImageResource(drawableId);}}/*** 為ImageView設(shè)置圖片* * @param imageViewId ImageView的id, 比如R.id.my_imageview* @param bmp Bitmap圖片*/public void setImageForView(int imageViewId, Bitmap bmp) {ImageView imageView = ViewFinder.findViewById(imageViewId);if (imageView != null) {imageView.setImageBitmap(bmp);}}/*** 為CheckBox設(shè)置是否選中* * @param checkViewId CheckBox的id* @param isCheck 是否選中*/public void setCheckForCheckBox(int checkViewId, boolean isCheck) {CheckBox checkBox = ViewFinder.findViewById(checkViewId);if (checkBox != null) {checkBox.setChecked(isCheck);}} }

ViewFinder輔助類

/*** view finder, 方便查找View。用戶須要在使用時(shí)調(diào)用initContentView,* 將Context和布局id傳進(jìn)來(lái),然后使用findViewById來(lái)獲取須要的view* ,findViewById為泛型方法,返回的view則直接是你接收的類型,而不須要進(jìn)行強(qiáng)制類型轉(zhuǎn)換.比方,* 曾經(jīng)我們?cè)贏ctivity中找一個(gè)TextView通常是這樣 : * TextView textView = (TextView)findViewById(viewId); * 假設(shè)頁(yè)面中的控件比較多,就會(huì)有非常多的類型轉(zhuǎn)換,而使用ViewFinder則免去了類型轉(zhuǎn)換,* 示比例如以下 : * TextView textView = ViewFinder.findViewById(viewId);* * @author mrsimple*/ public final class ViewFinder {/*** LayoutInflater*/static LayoutInflater mInflater;/*** 每項(xiàng)的View的sub view Map*/private static SparseArray<View> mViewMap = new SparseArray<View>();/*** Content View*/static View mContentView;/*** 初始化ViewFinder, 實(shí)際上是獲取到該頁(yè)面的ContentView.* * @param context* @param layoutId*/public static void initContentView(Context context, int layoutId) {mInflater = LayoutInflater.from(context);mContentView = mInflater.inflate(layoutId, null, false);if (mInflater == null || mContentView == null) {throw new RuntimeException("ViewFinder init failed, mInflater == null || mContentView == null.");}}/*** @return*/public static View getContentView() {return mContentView;}/*** @param viewId* @return*/@SuppressWarnings("unchecked")public static <T extends View> T findViewById(int viewId) {// 先從view map中查找,假設(shè)有的緩存的話直接使用,否則再?gòu)膍ContentView中找View tagetView = mViewMap.get(viewId);if (tagetView == null) {tagetView = mContentView.findViewById(viewId);mViewMap.put(viewId, tagetView);}return tagetView == null ? null : (T) mContentView.findViewById(viewId);} }

? ? ? ? ?代碼都在Github上了,請(qǐng)猛擊這里。

總結(jié)

以上是生活随笔為你收集整理的Android中适用于ListView、GridView等组件的通用Adapter的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。