展会信息港展会大全

android中继承BaseAdapter实现DataAdapter通用数据适配器
来源:互联网   发布日期:2015-10-02 16:17:12   浏览:2214次  

导读:试想下,数据适配器只是提供不同的数据并匹配界面中的组件以呈现不同的数据内容.那么就可以对界面组件与数据项入手进行修改.通常在BaseAdapter.getView中会使用ViewHolder...

试想下,数据适配器只是提供不同的数据并匹配界面中的组件以呈现不同的数据内容.那么就可以对界面组件与数据项入手进行修改.

通常在BaseAdapter.getView中会使用ViewHolder方式来缓存界面中的组件,以便提高性能.那我们可以定义一个DataViewHolder类

[java]

public class DataViewHolder {

HashMap<Integer,View> mapView = new HashMap<Integer,View>();

HashMap<String,Object> mapData = new HashMap<String,Object>();

public void setView(int key,View v){

this.mapView.put(key, v);

}

@SuppressWarnings("unchecked")

public <T> T getView(int key){

return (T)this.mapView.get(key);

}

@SuppressWarnings("unchecked")

public <T> T getView(Class<T> clazz, int key){

return (T)this.mapView.get(key);

}

public void setData(String key, Object value){

mapData.put(key, value);

}

@SuppressWarnings("unchecked")

public <T> T getData(String key){

return (T)mapData.get(key);

}

@SuppressWarnings("unchecked")

public <T> T getData(Class<T> clazz, String key){

return (T)mapData.get(key);

}

}

对界面组件入手时,我们需要一个方法来提供一组界面组件的ID号,便于在BaseAdapter.getView方法中获取该组件实例.

[java]

public int[] getFindViewByIDs() {

return new int[]{

R.id.ItemText,

R.id.ItemImage

};

}

在实现BaseAdapter.getView方法时,通常需要获取布局资源,那么我们提供一个方法

[java]

public View getLayout(int position, DataViewHolder vh) {

return inflater.inflate(R.layout.gv_content, null);

}

以便在BaseAdapter.getView方法中调用,我们来实现BaseAdapter.getView方法

[java]

public View getView(int position, View convertView, ViewGroup parent) {

DataViewHolder vh;

if(convertView == null){

vh = new DataViewHolder();

convertView = this.getLayout(position,vh); //获取布局资源

if(convertView == null)

return null;

int[] idAry = this.getFindViewByIDs(); //获取界面组件

if(idAry == null)idAry = new int[]{};

for(int id : idAry){

vh.setView(id, convertView.findViewById(id)); //资源id作为key,缓存界面中的组件

}

convertView.setTag(vh);

}

else

vh = (DataViewHolder)convertView.getTag();

this.renderData(position, vh); //继承类中的方法,完成数据到界面组件的赋值

return convertView;

}

对数据项入手时,我们只需要定义泛型参数来支持,先暂时定义为HashMap<String,String>, renderData方法如下

[java]

public void renderData(int position, DataViewHolder vh) {

HashMap<String,String> map = (HashMap<String,String>)this.getItem(position);

vh.getView(TextView.class, R.id.ItemText).setText(map.get("title"));

ImageView imgView = vh.getView(R.id.ItemImage);

imgView.setImageURI(...);

}

让我们来看一下完整的实现

[java]

public abstract class DataAdapter<TItem> extends BaseAdapter {

protected LayoutInflater inflater=null;

protected Context mContext;

private List<TItem> lst;

public DataAdapter(Context c, List<TItem> lst){

this.mContext = c;

this.lst = lst;

this.inflater=LayoutInflater.from(c);

}

@Override

public int getCount() {

return lst.size();

}

public void insert(TItem data){

lst.add(0, data);

this.notifyDataSetChanged();

}

public void append(TItem data){

lst.add(data);

this.notifyDataSetChanged();

}

public void replace(TItem data){

int idx = this.lst.indexOf(data);

this.replace(idx, data);

}

public void replace(int index, TItem data){

if(index<0)return;

if(index> lst.size()-1)return;

lst.set(index, data);

this.notifyDataSetChanged();

}

public List<TItem> getItems(){

return lst;

}

@Override

public Object getItem(int position) {

return lst.get(position);

}

public TItem getItemT(int position) {

return lst.get(position);

}

@Override

public long getItemId(int position) {

return position;

}

public void removeItem(int position){

if(lst.size()<=0)return;

if(position<0)return;

if(position>lst.size()-1)return;

lst.remove(position);

this.notifyDataSetChanged();

}

public void clear(){

lst.clear();

this.notifyDataSetChanged();

}

public abstract int[] getFindViewByIDs();

public abstract View getLayout(int position, DataViewHolder vh);

public final View getResourceView(int id){

return inflater.inflate(id, null);

}

@Override

public View getView(int position, View convertView, ViewGroup parent) {

DataViewHolder vh;

if(convertView == null){

vh = new DataViewHolder();

convertView = this.getLayout(position,vh);

if(convertView == null)

return null;

int[] idAry = this.getFindViewByIDs();

if(idAry == null)idAry = new int[]{};

for(int id : idAry){

vh.setView(id, convertView.findViewById(id));

}

convertView.setTag(vh);

}

else

vh = (DataViewHolder)convertView.getTag();

this.renderData(position, vh);

return convertView;

}

public abstract void renderData(int position, DataViewHolder vh);

}

实际使用,如何使用DataAdapter类呢?我们还是要继承来实现.

[java]

public class T1Activity extends Activity {

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_t1);

HashMap<String,String> map1 = new HashMap<String,String>();

map1.put("title","xxx");

map1.put("url","xxx");

...

List<HashMap<String,String>> al = new ArrayList<HashMap<String,String>>();

al.add(map1); //添加数据

al.add(map2); //添加数据

...

PrgmAdapter adapter = new PrgmAdapter(T1Activity.this, al); //实例化数据适配器

GridView gridview=(GridView)findViewById(R.id.gridView1);

gridview.setAdapter(adapter);

}

//实际使用要继承来实现.现在我们不需要关心getView方法了(除非有特殊需求),只需要提供布局资源,组件资源号,并在renderData中完成赋值就OK了.

private class PrgmAdapter extends DataAdapter<HashMap<String,String>>{

public PrgmAdapter(Context c, List<HashMap<String,String>> lst){

super(c,lst);

}

@Override

public int[] getFindViewByIDs() {

return new int[]{

R.id.ItemText,

R.id.ItemImage

};

}

@Override

public View getLayout(int position, DataViewHolder vh) {

return this.getResourceView(R.layout.gv_content);

}

@Override

public void renderData(int position, DataViewHolder vh) {

HashMap<String,String> map = this.getItemT(position);

vh.getView(TextView.class, R.id.ItemText).setText(map.get("title"));

ImageView imgView = vh.getView(R.id.ItemImage);

...

}

}

}

如果其他类型,例如String,则

[java]

class StrAdapter extends DataAdapter<String>{}

完全可以再进行调整,比如设置资源ID提供一个方法,在getView中使用.目前就可以基本使用满足通用性.

赞助本站

人工智能实验室

相关热词: android开发 教程

相关内容
AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港