写点什么

ListView Item 多布局的实现

作者:向阳逐梦
  • 2023-03-09
    四川
  • 本文字数:2927 字

    阅读完需:约 10 分钟

ListView Item多布局的实现

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

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

1.要点讲解:

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

2.代码实现:

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

MutiLayoutAdapter.java

/** * Created by Jay on 2015/9/23 0023. */public class MutiLayoutAdapter extends BaseAdapter{
//定义两个类别标志 private static final int TYPE_BOOK = 0; private static final int TYPE_APP = 1; private Context mContext; private ArrayList<Object> mData = null;

public MutiLayoutAdapter(Context mContext,ArrayList<Object> mData) { this.mContext = mContext; this.mData = mData; }
@Override public int getCount() { return mData.size(); }
@Override public Object getItem(int position) { return mData.get(position); }
@Override public long getItemId(int position) { return position; }
//多布局的核心,通过这个判断类别 @Override public int getItemViewType(int position) { if (mData.get(position) instanceof App) { return TYPE_APP; } else if (mData.get(position) instanceof Book) { return TYPE_BOOK; } else { return super.getItemViewType(position); } }
//类别数目 @Override public int getViewTypeCount() { return 2; }

@Override public View getView(int position, View convertView, ViewGroup parent) { int type = getItemViewType(position); ViewHolder1 holder1 = null; ViewHolder2 holder2 = null; if(convertView == null){ switch (type){ case TYPE_APP: holder1 = new ViewHolder1(); convertView = LayoutInflater.from(mContext).inflate(R.layout.item_one, parent, false); holder1.img_icon = (ImageView) convertView.findViewById(R.id.img_icon); holder1.txt_aname = (TextView) convertView.findViewById(R.id.txt_aname); convertView.setTag(R.id.Tag_APP,holder1); break; case TYPE_BOOK: holder2 = new ViewHolder2(); convertView = LayoutInflater.from(mContext).inflate(R.layout.item_two, parent, false); holder2.txt_bname = (TextView) convertView.findViewById(R.id.txt_bname); holder2.txt_bauthor = (TextView) convertView.findViewById(R.id.txt_bauthor); convertView.setTag(R.id.Tag_Book,holder2); break; } }else{ switch (type){ case TYPE_APP: holder1 = (ViewHolder1) convertView.getTag(R.id.Tag_APP); break; case TYPE_BOOK: holder2 = (ViewHolder2) convertView.getTag(R.id.Tag_Book); break; } }
Object obj = mData.get(position); //设置下控件的值 switch (type){ case TYPE_APP: App app = (App) obj; if(app != null){ holder1.img_icon.setImageResource(app.getaIcon()); holder1.txt_aname.setText(app.getaName()); } break; case TYPE_BOOK: Book book = (Book) obj; if(book != null){ holder2.txt_bname.setText(book.getbName()); holder2.txt_bauthor.setText(book.getbAuthor()); } break; } return convertView; }

//两个不同的ViewHolder private static class ViewHolder1{ ImageView img_icon; TextView txt_aname; }
private static class ViewHolder2{ TextView txt_bname; TextView txt_bauthor; }}
复制代码

这里有个地方要注意的,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 中添加:

<item name="Tag_APP" type="id"></item><item name="Tag_Book" type="id"></item>
复制代码

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


MainActivity.java

public class MainActivity extends AppCompatActivity {
private static final int TYPE_BOOK = 0; private static final int TYPE_APP = 1; private ListView list_content; private ArrayList<Object> mData = null; private MutiLayoutAdapter myAdapter = null;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
//数据准备: mData = new ArrayList<Object>(); for(int i = 0;i < 20;i++){ switch ((int)(Math.random() * 2)){ case TYPE_BOOK: mData.add(new Book("《第一行代码》","郭霖")); break; case TYPE_APP: mData.add(new App(R.mipmap.iv_icon_baidu,"百度")); break; } }
list_content = (ListView) findViewById(R.id.list_content); myAdapter = new MutiLayoutAdapter(MainActivity.this,mData); list_content.setAdapter(myAdapter); }}
复制代码

3.代码下载:

ListViewDemo6.zip

发布于: 刚刚阅读数: 7
用户头像

向阳逐梦

关注

人生享受编程,编程造就人生! 2022-06-01 加入

某公司芯片测试工程师,嵌入式开发工程师,InfoQ签约作者,阿里云星级博主,华为云·云享专家。座右铭:向着太阳,追逐梦想!

评论

发布
暂无评论
ListView Item多布局的实现_ListView_向阳逐梦_InfoQ写作社区