打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
使用ListView进行不同布局ItemView的显示

实现的界面效果如下图所示,没有可以进行布局上的调整,所以看起来丑一点。

上图在一个ListView中显示了两种不同的ItemView,主要是使用BaseAdapter中的getItemViewType()方法,以及getViewTypeCount()方法实现的。

下面来说说详细的实现步骤:

1. 跟以前使用自定义adapter时一样,都需要编写itemView的xml布局文件。只不过在此例中需要编写两个xml布局文件,分别对应了两个不同的itemView。两个xml文件的代码如下:

布局1

布局2

2.自定义一个Adapter类继承自BaseAdapter。并实现 getItemViewType()方法,以及getViewTypeCount()方法。顾名思义,getItemViewType()方法是用来获取当前需要绘制的itemView的类型,getViewTypeCount()方法是用来获取不同的itemview的种类数,即总共有多少种不同种类的itemView。

自定义适配器的代码如下:

/** * Created by Kent on 2014/12/12. */public class MyAdapter extends BaseAdapter {  private Context mContext = null;//上下文  private LayoutInflater mInflater = null;  private List mData = null;//要显示的数据  public MyAdapter(Context context, List data){    this.mInflater = LayoutInflater.from(context);    this.mData = data;  }  //添加一个新的Item,并通知listview进行显示刷新  public void addItem(BaseItem newItem){    this.mData.add(newItem);    this.notifyDataSetChanged();  }  @Override  public int getItemViewType(int position) {    return mData.get(position).getItem_type();  }  @Override  public int getViewTypeCount() {    return ItemType.ITEM_TYPE_MAX_COUNT;  }  @Override  public int getCount() {    if(mData == null){      return 0;    }    return this.mData.size();  }  @Override  public Object getItem(int i) {    return mData.get(i);  }  @Override  public long getItemId(int i) {    return i;  }  @Override  public View getView(int position, View convertView, ViewGroup viewGroup) {    View viewItem1 = null;    View viewItem2 = null;    int itemType = this.getItemViewType(position);    if(itemType == ViewHolder1.ITEM_VIEW_TYPE_1){      //第一种item      ViewHolder1 viewHolder1 = null;      if(convertView == null){        //没有缓存过        viewHolder1 = new ViewHolder1();        viewItem1 = this.mInflater.inflate(R.layout.list_view_item_1, null, false);        viewHolder1.textView = (TextView)viewItem1.findViewById(R.id.            main_activity_list_view_item_1_textview);        viewHolder1.imageView = (ImageView)viewItem1.findViewById(R.id.            main_activity_list_view_item_1_imageview);        viewItem1.setTag(viewHolder1);        convertView = viewItem1;      }else{        viewHolder1 = (ViewHolder1)convertView.getTag();      }      viewHolder1.textView.setText(((ItemBean1) mData.get(position)).getName());      viewHolder1.imageView.setBackgroundResource(R.drawable.ic_launcher);    }else if(itemType == ViewHolder2.ITEM_VIEW_TYPE_2){      //第二种item      ViewHolder2 viewHolder2 = null;      if(convertView == null){        //没有缓存过        viewHolder2 = new ViewHolder2();        viewItem2 = this.mInflater.inflate(R.layout.list_view_item_2, null, false);        viewHolder2.textView1 = (TextView)viewItem2.findViewById(R.id.            main_activity_list_view_item_2_textview);        viewHolder2.textView2 = (TextView)viewItem2.findViewById(R.id.            main_activity_list_view_item_2_textview_2);        viewItem2.setTag(viewHolder2);        convertView = viewItem2;      }else{        viewHolder2 = (ViewHolder2)convertView.getTag();      }      viewHolder2.textView1.setText(((ItemBean2)mData.get(position)).getName());      viewHolder2.textView2.setText(((ItemBean2)mData.get(position)).getAddress());    }    return convertView;  }}
首先要说一下listview的绘制原理,在listview进行绘制的时候,首先要调用getCount()方法来确定listview的item个数,然后在绘制每个item的时候调用getView方法来进行绘制,而getItem和getItemId是在listview响应用户操作时间时候进行调用的。

这里着重介绍一下getView()方法,这个方法是在绘制每个item时进行调用的,它返回一个View对象,而此View就是需要绘制的View。

public View getView(int position, View convertView, ViewGroup viewGroup) :其中position参数为当前绘制的item的位置,convertView参数为当前要绘制的View,这个参数主要用来缓存,viewGroup参数是当前view的父控件。

关于 getItemViewType()方法,以及getViewTypeCount()方法将在稍后进行讨论。

3. listview数据源:

通常listview里面的数据是来源于一个list集合,而list集合中的元素是Map类型的数据。即:List<>>每个map类型的数据对应了一个itemview中需要显示的内容。而本例中定义数据源是来自对象的,由于本例要显示不同的item,所以我们自定义出两个Bean,分别对应两种item中的数据。代码如下:

/** * Created by Kent on 2014/12/15. */public class BaseItem {  private int item_type = 0;  public BaseItem(int item_type) {    this.item_type = item_type;  }  public int getItem_type() {    return item_type;  }  public void setItem_type(int item_type) {    this.item_type = item_type;  }}
由于每个Item都需要一个type类型的变量来标识当前Item的种类,所以定义了一个基类:BaseItem类,它只包含一个item_type的属性,用来标识item的种类。

两个继承自它的子类:

/** * Created by Kent on 2014/12/15. */public class ItemBean1 extends BaseItem{  private String name = null;  private String imagePath = null;  public ItemBean1(int item_type, String name, String imagePath) {    super(item_type);    this.name = name;    this.imagePath = imagePath;  }  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }  public String getImagePath() {    return imagePath;  }  public void setImagePath(String imagePath) {    this.imagePath = imagePath;  }  public int getItemType(){    return super.getItem_type();  }  public void setItemType(int itemType){    super.setItem_type(itemType);  }}
4. MainActivity中的代码:
public class MainActivity extends Activity {  private ListView listView  = null;  //适配器  private MyAdapter myAdapter = null;  //数据  private List mData = null;  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    findViewsById();;    init();    addListeners();  }  private void findViewsById(){    this.listView = (ListView)findViewById(R.id.main_activity_listview);  }  private void init(){    this.mData = new ArrayList();    this.mData.add(new ItemBean1(ViewHolder1.ITEM_VIEW_TYPE_1, "name1", "iamgePath1"));    this.mData.add(new ItemBean1(ViewHolder1.ITEM_VIEW_TYPE_1, "name2", "iamgePath2"));    this.mData.add(new ItemBean1(ViewHolder1.ITEM_VIEW_TYPE_1, "name2", "iamgePath2"));    this.mData.add(new ItemBean2(ViewHolder2.ITEM_VIEW_TYPE_2, "name1", "address1"));    this.mData.add(new ItemBean2(ViewHolder2.ITEM_VIEW_TYPE_2, "name1", "address1"));    this.mData.add(new ItemBean2(ViewHolder2.ITEM_VIEW_TYPE_2, "name1", "address1"));    this.mData.add(new ItemBean1(ViewHolder1.ITEM_VIEW_TYPE_1, "name2", "iamgePath2"));    this.mData.add(new ItemBean2(ViewHolder2.ITEM_VIEW_TYPE_2, "name1", "address1"));    this.mData.add(new ItemBean1(ViewHolder1.ITEM_VIEW_TYPE_1, "name2", "iamgePath2"));    this.mData.add(new ItemBean1(ViewHolder1.ITEM_VIEW_TYPE_1, "name2", "iamgePath2"));    this.mData.add(new ItemBean1(ViewHolder1.ITEM_VIEW_TYPE_1, "name2", "iamgePath2"));    this.mData.add(new ItemBean2(ViewHolder2.ITEM_VIEW_TYPE_2, "name1", "address1"));    this.mData.add(new ItemBean2(ViewHolder2.ITEM_VIEW_TYPE_2, "name1", "address1"));    this.mData.add(new ItemBean1(ViewHolder1.ITEM_VIEW_TYPE_1, "name2", "iamgePath2"));    this.mData.add(new ItemBean1(ViewHolder1.ITEM_VIEW_TYPE_1, "name2", "iamgePath2"));    this.mData.add(new ItemBean1(ViewHolder1.ITEM_VIEW_TYPE_1, "name2", "iamgePath2"));    this.mData.add(new ItemBean1(ViewHolder1.ITEM_VIEW_TYPE_1, "name2", "iamgePath2"));    this.mData.add(new ItemBean2(ViewHolder2.ITEM_VIEW_TYPE_2, "name1", "address1"));    this.mData.add(new ItemBean2(ViewHolder2.ITEM_VIEW_TYPE_2, "name1", "address1"));    this.mData.add(new ItemBean1(ViewHolder1.ITEM_VIEW_TYPE_1, "name2", "iamgePath2"));    this.mData.add(new ItemBean1(ViewHolder1.ITEM_VIEW_TYPE_1, "name2", "iamgePath2"));    this.mData.add(new ItemBean1(ViewHolder1.ITEM_VIEW_TYPE_1, "name2", "iamgePath2"));    this.mData.add(new ItemBean1(ViewHolder1.ITEM_VIEW_TYPE_1, "name2", "iamgePath2"));    this.mData.add(new ItemBean1(ViewHolder1.ITEM_VIEW_TYPE_1, "name2", "iamgePath2"));    this.mData.add(new ItemBean2(ViewHolder2.ITEM_VIEW_TYPE_2, "name1", "address1"));    this.myAdapter = new MyAdapter(this, this.mData);    this.listView.setAdapter(this.myAdapter);  }  private void addListeners(){  }}
5. ViewHolder,用于ItemView的缓存优化:
/** * Created by Kent on 2014/12/12. */public final class ViewHolder1 {  public static final int ITEM_VIEW_TYPE_1 = 0;  public TextView textView = null;  public ImageView imageView = null;}
/** * Created by Kent on 2014/12/12. */public final class ViewHolder2 {  public static final int ITEM_VIEW_TYPE_2 = 1;  public TextView textView1 = null;  public TextView textView2 = null;}
/** * Created by Kent on 2014/12/15. */public class ItemType {    public static final int ITEM_TYPE_MAX_COUNT = 2;}
6. 实现不同item类型的显示;

首先来看下getItemViewType()方法;

public int getItemViewType(int position) {        return mData.get(position).getItem_type();    }
这个方法返回了当前要绘制的ItemView的类型,类型数据存储在listView的数据源List中的每个bean的itemType属性中。

再来看看getViewTypeCount()方法:

public int getViewTypeCount() {        return ItemType.ITEM_TYPE_MAX_COUNT;    }
这个方法返回了不同Item的种类个数。

最后来看看最重要的getView()方法:

public View getView(int position, View convertView, ViewGroup viewGroup) {    View viewItem1 = null;    View viewItem2 = null;    int itemType = this.getItemViewType(position);    if(itemType == ViewHolder1.ITEM_VIEW_TYPE_1){      //第一种item      ViewHolder1 viewHolder1 = null;      if(convertView == null){        //没有缓存过        viewHolder1 = new ViewHolder1();        viewItem1 = this.mInflater.inflate(R.layout.list_view_item_1, null, false);        viewHolder1.textView = (TextView)viewItem1.findViewById(R.id.            main_activity_list_view_item_1_textview);        viewHolder1.imageView = (ImageView)viewItem1.findViewById(R.id.            main_activity_list_view_item_1_imageview);        viewItem1.setTag(viewHolder1);        convertView = viewItem1;      }else{        viewHolder1 = (ViewHolder1)convertView.getTag();      }      viewHolder1.textView.setText(((ItemBean1) mData.get(position)).getName());      viewHolder1.imageView.setBackgroundResource(R.drawable.ic_launcher);    }else if(itemType == ViewHolder2.ITEM_VIEW_TYPE_2){      //第二种item      ViewHolder2 viewHolder2 = null;      if(convertView == null){        //没有缓存过        viewHolder2 = new ViewHolder2();        viewItem2 = this.mInflater.inflate(R.layout.list_view_item_2, null, false);        viewHolder2.textView1 = (TextView)viewItem2.findViewById(R.id.            main_activity_list_view_item_2_textview);        viewHolder2.textView2 = (TextView)viewItem2.findViewById(R.id.            main_activity_list_view_item_2_textview_2);        viewItem2.setTag(viewHolder2);        convertView = viewItem2;      }else{        viewHolder2 = (ViewHolder2)convertView.getTag();      }      viewHolder2.textView1.setText(((ItemBean2)mData.get(position)).getName());      viewHolder2.textView2.setText(((ItemBean2)mData.get(position)).getAddress());    }    return convertView;  }
前面已经说过了,getView是在每个Item进行绘制的时候进行调用的,那么想要进行不同类型Item的显示,在这个方法中根据item的类型进行不同的绘制就可以了。
首先,通过
int itemType = this.getItemViewType(position);
获取到当前要绘制的Item的种类。然后根据不同的种类进行不同的布局导入。
viewItem1 = this.mInflater.inflate(R.layout.list_view_item_1, null, false);

这个方法使用了ViewHolder进行itemView的缓存。有关内容在此不做解释

源码下载地址:http://download.csdn.net/detail/hhzz1504042001/8262015

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
[Android] ListView中getView的原理+如何在ListView中放置多个item
安卓开发笔记(十):升级ListView为RecylerView的使用
Android开发:实现带图片和checkbox的listview - Android开发...
为ListView每个Item上面的按钮添加事件
HowTo: ListView, Adapter, getView and different list items’ layouts in one ListView | Android Tales
为RecyclerView打造通用Adapter
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服