加载中...

2.5.1 ListView Item多布局的实现


本节引言:

本节是ListView这个小节的最后一节,给大家带来的是ListView多布局Item的实现, 何为ListView Item多布局,打个比方,QQ这种聊天列表:

假如他是用一个ListView做的,那么一个ListView上不就有两种不同的Item咯! 一左一右,嘿嘿,本节就来教大家如何实现ListView的多布局!

1.要点讲解:

重写getItemViewType()方法对应View是哪个类别,以及getViewTypeCount()方法iew返回 总共多少个类别!然后再getView那里调用getItemViewType获得对应类别,再加载对应的View!

2.代码实现:

这里的话直接用上一节的两个布局,然后另外写一个Adapter重写要点中的几个几个地方:

MutiLayoutAdapter.java

  1. /**
  2.  * Created by Jay on 2015/9/23 0023.
  3.  */
  4. public class MutiLayoutAdapter extends BaseAdapter{
  5.  
  6.     //定义两个类别标志
  7.     private static final int TYPE_BOOK = 0;
  8.     private static final int TYPE_APP = 1;
  9.     private Context mContext;
  10.     private ArrayList<Object> mData = null;
  11.  
  12.  
  13.     public MutiLayoutAdapter(Context mContext,ArrayList<Object> mData) {
  14.         this.mContext = mContext;
  15.         this.mData = mData;
  16.     }
  17.  
  18.     @Override
  19.     public int getCount() {
  20.         return mData.size();
  21.     }
  22.  
  23.     @Override
  24.     public Object getItem(int position) {
  25.         return mData.get(position);
  26.     }
  27.  
  28.     @Override
  29.     public long getItemId(int position) {
  30.         return position;
  31.     }
  32.  
  33.     //多布局的核心,通过这个判断类别
  34.     @Override
  35.     public int getItemViewType(int position) {
  36.         if (mData.get(position) instanceof App) {
  37.             return TYPE_APP;
  38.         } else if (mData.get(position) instanceof Book) {
  39.             return TYPE_BOOK;
  40.         } else {
  41.             return super.getItemViewType(position);
  42.         }
  43.     }
  44.  
  45.     //类别数目
  46.     @Override
  47.     public int getViewTypeCount() {
  48.         return 2;
  49.     }
  50.  
  51.  
  52.     @Override
  53.     public View getView(int position, View convertView, ViewGroup parent) {
  54.         int type = getItemViewType(position);
  55.         ViewHolder1 holder1 = null;
  56.         ViewHolder2 holder2 = null;
  57.         if(convertView == null){
  58.            switch (type){
  59.                case TYPE_APP:
  60.                    holder1 = new ViewHolder1();
  61.                    convertView = LayoutInflater.from(mContext).inflate(R.layout.item_one, parent, false);
  62.                    holder1.img_icon = (ImageView) convertView.findViewById(R.id.img_icon);
  63.                    holder1.txt_aname = (TextView) convertView.findViewById(R.id.txt_aname);
  64.                    convertView.setTag(R.id.Tag_APP,holder1);
  65.                    break;
  66.                case TYPE_BOOK:
  67.                    holder2 = new ViewHolder2();
  68.                    convertView = LayoutInflater.from(mContext).inflate(R.layout.item_two, parent, false);
  69.                    holder2.txt_bname = (TextView) convertView.findViewById(R.id.txt_bname);
  70.                    holder2.txt_bauthor = (TextView) convertView.findViewById(R.id.txt_bauthor);
  71.                    convertView.setTag(R.id.Tag_Book,holder2);
  72.                    break;
  73.            }
  74.         }else{
  75.             switch (type){
  76.                 case TYPE_APP:
  77.                     holder1 = (ViewHolder1) convertView.getTag(R.id.Tag_APP);
  78.                     break;
  79.                 case TYPE_BOOK:
  80.                     holder2 = (ViewHolder2) convertView.getTag(R.id.Tag_Book);
  81.                     break;
  82.             }
  83.         }
  84.  
  85.         Object obj = mData.get(position);
  86.         //设置下控件的值
  87.         switch (type){
  88.             case TYPE_APP:
  89.                 App app = (App) obj;
  90.                 if(app != null){
  91.                     holder1.img_icon.setImageResource(app.getaIcon());
  92.                     holder1.txt_aname.setText(app.getaName());
  93.                 }
  94.                 break;
  95.             case TYPE_BOOK:
  96.                 Book book = (Book) obj;
  97.                 if(book != null){
  98.                     holder2.txt_bname.setText(book.getbName());
  99.                     holder2.txt_bauthor.setText(book.getbAuthor());
  100.                 }
  101.                 break;
  102.         }
  103.         return convertView;
  104.     }
  105.  
  106.  
  107.     //两个不同的ViewHolder
  108.     private static class ViewHolder1{
  109.         ImageView img_icon;
  110.         TextView txt_aname;
  111.     }
  112.  
  113.     private static class ViewHolder2{
  114.         TextView txt_bname;
  115.         TextView txt_bauthor;
  116.     }
  117. }

这里有个地方要注意的,convertView.setTag(R.id.Tag_APP,holder1);我们平时都直接 setTag(Object)的,这个是setTag的重载方法,参数是一个唯一的key以及后面的一个对象! 唯一!!!我一开始直接把TYPE_BOOK作为第一个参数,然后就报下面这个错误:

The key must be an application-specific resource id就是前面这个要唯一,定义一个final类型的int变量和硬编码一个值的方式都是行不通的 这里的做法是直接在strings.xml中添加:

  1. <item name="Tag_APP" type="id"></item>
  2. <item name="Tag_Book" type="id"></item>

当然你也可以在res/values/下另外创建一个ids.xml文件,把上面这段代码贴上去! 除了这个还有一个要注意的地方,就是这个区分类别的标志要从0开始算,不然会报下面 这样的错误:

MainActivity.java

  1. public class MainActivity extends AppCompatActivity {
  2.  
  3.     private static final int TYPE_BOOK = 0;
  4.     private static final int TYPE_APP = 1;
  5.     private ListView list_content;
  6.     private ArrayList<Object> mData = null;
  7.     private MutiLayoutAdapter myAdapter = null;
  8.  
  9.     @Override
  10.     protected void onCreate(Bundle savedInstanceState) {
  11.         super.onCreate(savedInstanceState);
  12.         setContentView(R.layout.activity_main);
  13.  
  14.         //数据准备:
  15.         mData = new ArrayList<Object>();
  16.         for(int i = 0;< 20;i++){
  17.             switch ((int)(Math.random() * 2)){
  18.                 case TYPE_BOOK:
  19.                     mData.add(new Book("《第一行代码》","郭霖"));
  20.                     break;
  21.                 case TYPE_APP:
  22.                     mData.add(new App(R.mipmap.iv_icon_baidu,"百度"));
  23.                     break;
  24.             }
  25.         }
  26.  
  27.         list_content = (ListView) findViewById(R.id.list_content);
  28.         myAdapter = new MutiLayoutAdapter(MainActivity.this,mData);
  29.         list_content.setAdapter(myAdapter);
  30.     }
  31. }

上面随机生成0和1,0就往集合中添加一个Book的对象,1的话就添加一个App的对象!


本节小结:

好的,本节给大家讲解了ListView Item多布局的实现,就是两个方法的重写, 然后getView()做下判断,设置不同的布局而已~代码非常简单~

关于ListView的知识就告一段落吧,当然ListView的知识并不止这些, 异步加载,优化等等,这些我们都会在进阶部分进行学习~就说这么多,谢谢~


第 1-1 条, 共 1 条.
我辈年轻 2016-08-14 12:32:09
这里没有说明代码中的book 和 app 是什么类回复