編輯:關於Android編程
ListView是App開發中最常見的控件之一了,與之相隨的則是BaseAdapter的使用,BaseAdapter的作用則是為我們的ListView提供數據源,普通的用法相信大家都會用,今天主要說明一下,列表中如果有多種樣式的ItemView時,應該如何去高效的加載.
先看一下效果圖:

如圖所示:整個列表中存在著兩種樣式的ItemView,開始用傳統的ConvertView去緩存子項時,發現兩種布局一滑動就出現了錯亂,後來為了項目進度,看到沒有發生內存溢出後就沒有用ConvertView做子View的緩存,今天在翻看Adapter及其子類的源碼時發現,如下代碼,瞬間想到之前沒有對多布局多緩存的問題,於是上網查看了一下,果然就是用這幾個方法去實現,代碼如下:
public interface Adapter {
void registerDataSetObserver(DataSetObserver observer);
void unregisterDataSetObserver(DataSetObserver observer);
int getCount();
Object getItem(int position);
long getItemId(int position);
boolean hasStableIds();
View getView(int position, View convertView, ViewGroup parent);
static final int IGNORE_ITEM_VIEW_TYPE = AdapterView.ITEM_VIEW_TYPE_IGNORE;
int getItemViewType(int position); //方法一,得到布局類型
int getViewTypeCount(); // 方法二,得到布局總
static final int NO_SELECTION = Integer.MIN_VALUE;
/**
* @return true if this adapter doesn't contain any data. This is used to determine
* whether the empty view should be displayed. A typical implementation will return
* getCount() == 0 but since getCount() includes the headers and footers, specialized
* adapters might want a different behavior.
*/
boolean isEmpty();
}
package android.widget;
import android.database.DataSetObservable;
import android.database.DataSetObserver;
import android.view.View;
import android.view.ViewGroup;
public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {
private final DataSetObservable mDataSetObservable = new DataSetObservable();
public boolean hasStableIds() {
return false;
}
public void registerDataSetObserver(DataSetObserver observer) {
mDataSetObservable.registerObserver(observer);
}
public void unregisterDataSetObserver(DataSetObserver observer) {
mDataSetObservable.unregisterObserver(observer);
}
public void notifyDataSetChanged() {
mDataSetObservable.notifyChanged();
}
public void notifyDataSetInvalidated() {
mDataSetObservable.notifyInvalidated();
}
public boolean areAllItemsEnabled() {
return true;
}
public boolean isEnabled(int position) {
return true;
}
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return getView(position, convertView, parent);
}
public int getItemViewType(int position) {
return 0;
}
public int getViewTypeCount() {
return 1;
}
public boolean isEmpty() {
return getCount() == 0;
}
}
有了這兩個方法後,我們只需重寫這兩個方法即可,下面是我重寫的Adapter代碼:
/**********************************************************
* @文件名稱:CountryListAdapter.java
* @文件作者:rzq
* @創建時間:2014年7月22日 下午2:33:43
* @文件描述:國家列表適配器
* @修改歷史:2014年7月22日創建初始版本
**********************************************************/
public class CountryListAdapter extends BaseAdapter {
private Context mContext;
private ArrayList dataList;
private Country country;
private ViewHolder holder1;
private ViewHolder holder2;
public CountryListAdapter(Context context, ArrayList dataList) {
this.mContext = context;
this.dataList = dataList;
}
@Override
public int getCount() {
return dataList.size();
}
@Override
public Object getItem(int position) {
return dataList.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
country = (Country) dataList.get(position);
int type = getItemViewType(position);
if (convertView == null) {
switch (type) {
case 0:
holder1 = new ViewHolder();
convertView = LayoutInflater.from(mContext)
.inflate(R.layout.catagories_expandlistview_group,
parent, false);
holder1.textView = (TextView) convertView
.findViewById(R.id.catagories_group_textview);
convertView.setTag(holder1);
break;
case 1:
holder2 = new ViewHolder();
convertView = LayoutInflater.from(mContext).inflate(
R.layout.register_expandlistview_child, parent, false);
holder2.textView = (TextView) convertView
.findViewById(R.id.register_child_textview);
holder2.imageView = (ImageView) convertView
.findViewById(R.id.register_country_flag);
convertView.setTag(holder2);
break;
}
} else {
switch (type) {
case 0:
holder1 = (ViewHolder) convertView.getTag();
break;
case 1:
holder2 = (ViewHolder) convertView.getTag();
break;
}
}
switch (type) {
case 0:
holder1.textView.setText(country.getIndexChar());
break;
case 1:
holder2.textView.setText(country.getCountryName());
holder2.imageView.setImageDrawable(country.getFlagDrawable());
break;
}
return convertView;
}
@Override
public int getItemViewType(int position) {
country = (Country) getItem(position);
if (country.isGroup()) {
return 0;
} else {
return 1;
}
}
@Override
public int getViewTypeCount() {
return 2;
}
private static class ViewHolder {
private TextView textView;
private ImageView imageView;
}
}
這樣確保了內存不會溢出.也可以提高ListView的加載效率.
Android實戰技巧之四十八:Android上的Java8和kotlin
Java和Android這對搭檔目前也在風雨飄搖中。技術圈子的事,往往被商業利益牽著鼻子走。世事莫過於此。Java8目前Android應用開發已經使用到Java7,但對J
小米5、榮耀V8、魅族PRO6和一加手機3哪個好 參數對比評測
國產手機的集體高潮,卻使消費者變的“煩惱了”,因為消費者在購買手機時變得越來越猶豫糾結。以2499元這個價位的手機來說,單國產手機就
android編程之XML文件解析方法詳解(附源碼)
本文實例講述了android編程之XML文件解析方法。分享給大家供大家參考,具體如下:在android開發中,經常用到去解析xml文件,常見的解析xml的方式有一下三種:
Android開發中ListView自定義adapter的封裝
【引入】 我們一般編寫listView的時候順序是這樣的: •需要展示的數據集List<T> •為這個數