Android簡便通用的SimpleBaseAdapter
在Android開發中經常用到ListView、GridView等列表,於是Adapter也就比較常用的了, 而實際專案中稍微複雜點的基本都會用到BaseAdapter, 大家都知道繼承自BaseAdapter必須要重寫getCount(), getItem(), getItemId(), getView()這幾個方法, 而且可能為了優化列表的載入還還會經常採用ViewHoder模式, 試想列表多了估計都寫煩了吧,那麼今天就來教大家一種通用、簡潔的Adapter,以後你就可以幾行程式碼搞定一個複雜的Adapter了。
通用的SimpleBaseAdapter
首先我們來解決每次都重寫BaseAdapter的那幾個方法的問題,解決方案很簡單,直接寫一個抽象的SimpleBaseAdapter,程式碼如下
public abstract class SimpleBaseAdapter<T> extends BaseAdapter {
protected Context context;
protected List<T> data;
public SimpleBaseAdapter(Context context, List<T> data) {
this.context = context;
this.data = data == null ? new ArrayList<T>() : data;
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
if (position >= data.size())
return null;
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
}
上面程式碼我不就過多解釋了,相信大家都能看懂。之後建立Adapter的時候只需要繼承自SimpleBaseAdapter,把List資料來源傳進去,再重寫getView方法就好了。
通用的ViewHolder
上面的SimpleBaseAdapter已經大大減少了不少的重複性工作,但是對於ViewHolder的優化依然還有很多重複性的程式碼要寫,那麼下面就來看看如何打造一個通用的ViewHolder。
關於ListView的優化這裡再多說下吧,主要是兩點:一是判斷convertView為空的時候才會inflate,複用item view,二便是使用ViewHoder模式,通過convertView.setTag與convertView進行繫結,然後當convertView複用時,直接從與之對於的ViewHolder(getTag)中拿到convertView佈局中的控制元件,省去了findViewById的時間~
下面看我們的ViewHolder類:
public class ViewHolder {
private SparseArray<View> views = new SparseArray<View>();
private View convertView;
public ViewHolder(View convertView) {
this.convertView = convertView;
}
public <T extends View> T getView(int resId) {
View v = views.get(resId);
if (null == v) {
v = convertView.findViewById(resId);
views.put(resId, v);
}
return (T) v;
}
}
可以看到這裡定義的ViewHolder程式碼很簡單,使用起來也是非常的輕便。SparseArray在程式碼理解上等價於HashMap<Integer, View>, SparseArray是Android提供的一個資料結構,但是比Map的效率更高。
最終的SimpleBaseAdapter
廢話不多說了,我們結合以上兩點,直接上個最終的SimpleBaseAdapter
public abstract class SimpleBaseAdapter<T> extends BaseAdapter {
protected Context context;
protected List<T> data;
public SimpleBaseAdapter(Context context, List<T> data) {
this.context = context;
this.data = data == null ? new ArrayList<T>() : new ArrayList<T>(data);
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
if (position >= data.size())
return null;
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
/**
* 該方法需要子類實現,需要返回item佈局的resource id
*
* @return
*/
public abstract int getItemResource();
/**
* 使用該getItemView方法替換原來的getView方法,需要子類實現
*
* @param position
* @param convertView
* @param parent
* @param holder
* @return
*/
public abstract View getItemView(int position, View convertView, ViewHolder holder);
@SuppressWarnings("unchecked")
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (null == convertView) {
convertView = View.inflate(context, getItemResource(), null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
return getItemView(position, convertView, holder);
}
public class ViewHolder {
private SparseArray<View> views = new SparseArray<View>();
private View convertView;
public ViewHolder(View convertView) {
this.convertView = convertView;
}
@SuppressWarnings("unchecked")
public <T extends View> T getView(int resId) {
View v = views.get(resId);
if (null == v) {
v = convertView.findViewById(resId);
views.put(resId, v);
}
return (T) v;
}
}
public void addAll(List<T> elem) {
data.addAll(elem);
notifyDataSetChanged();
}
public void remove(T elem) {
data.remove(elem);
notifyDataSetChanged();
}
public void remove(int index) {
data.remove(index);
notifyDataSetChanged();
}
public void replaceAll(List<T> elem) {
data.clear();
data.addAll(elem);
notifyDataSetChanged();
}
}
使用
自己的Adapter需要繼承SimpleBaseAdapter,並且實現getItemResource和getItemView兩個方法就好了, 下面看下例子:
public class TestFoodListAdapter extends SimpleBaseAdapter<String> {
public TestFoodListAdapter(Context context, List<String> data) {
super(context, data);
}
@Override
public int getItemResource() {
return R.layout.listitem_test;
}
@Override
public View getItemView(int position, View convertView, ViewHolder holder) {
TextView text = holder.getView(R.id.text);
text.setText(getItem(position));
return convertView;
}
}
相信大家都能看懂,具體的xml佈局檔案就不寫出來了,上面的示例和google推薦的寫法類似,只不過稍加變通之後減少了很多重複的程式碼, 是不是清爽了很多呢?
相關文章
- Android RecyclerView的簡便寫法AndroidView
- 輕量簡便的android沉浸式狀態列Android
- 簡便地Android崩潰日誌收集Android
- 使用struts,ibaits和JSTL開發簡便通用的檔案上傳系統AIJS
- Laravel Auth 更為簡便的使用Laravel
- springBoot超級簡便的分頁Spring Boot
- Android開發資料便籤Android
- 映象安裝pytorch的簡便方法總結PyTorch
- iFastZip for Mac:快速、簡便的檔案壓縮利器!ASTMac
- Android通用流行框架大全Android框架
- Android 封裝一個通用的PopupWindowAndroid封裝
- 三種提高Python程式碼效能的簡便方法Python
- NLPIR平臺提供快捷簡便的語義分析工具
- UKTools:安裝最新 Linux 核心的簡便方法Linux
- 最簡便的備份MySql資料庫方法(轉)MySql資料庫
- Android RecyclerView 通用介面卡的實現AndroidView
- 雲開發初探 —— 更簡便的小程式開發模式模式
- GeoPackage - 一個簡便輕量的本地地理資料庫Package資料庫
- 一個簡單輕便的移動支付整合庫FastPayAST
- Laravel 中除錯輸出 SQL 語句的簡便方法Laravel除錯SQL
- Ubuntu中編譯連結Opencv應用的簡便方式Ubuntu編譯OpenCV
- thinkphp開發的簡單通用CMS系統PHP
- entitybuilder--一個簡單的業務通用框架UI框架
- 通用、封裝、簡化 webpack 配置封裝Web
- 一個網站故障排查的、程式碼更新的簡便指令碼網站指令碼
- 一個出於ARouter,卻更輕便簡潔的Route工具
- 脫ASPack2.12加殼的DLL檔案簡便方法
- debian Linux下製作deb包的簡便方法(轉)Linux
- Android通用UI元件之DialogAndroidUI元件
- 15 個 Android 通用流行框架大全Android框架
- iOS 用簡便的方法統計兩個陣列中不同的元素iOS陣列
- Android擴充系列(11)--打造Windows下便攜的Android原始碼閱讀環境AndroidWindows原始碼
- B21 Invest,為加密資產投資者提供更簡便的通道加密
- Java Web應用下實現定時任務的簡便方法JavaWeb
- 線上生成佔點陣圖片工具:簡便快捷的設計利器
- Android 實現一個通用的圓角佈局Android
- Android應用開發完全退出程式的通用方法!!!Android
- 分享一下禁用 ESLint 的簡便方法,順便嘮叨一下程式碼規範的現狀與將來EsLint