listview如何实现单选一个复杂的ListView

21494人阅读
Android(56)
使用BaseAdapter实现复杂的ListView的步骤:
1. 数据你要准备好 List getData()。
2. 继承ListActivity专有屏,不再需要setContentView(xxx)。&
3. 创建一个继承自BaseAdapter的类。
4. 为List绑定适配器 setListAdapter(adapter)。
5. 用传统的方式来覆写适配器的getView函数 &(从参数convertView里映射布局文件,find各个控件填充数据)。
6. 改写:加入ViewHolder类(定义n个控件的声明) 。 &用convertView.setTag(viewHolder)在View和Object之间进行关联.。
7. 给按钮注册点击监听器。可以用Toast或AlertDialogue弹出选择项的数据。
friend_list.xml文件
&?xml version=&1.0& encoding=&utf-8&?&
&!-- 这是范例ListView的布局文件,出了ListView,还可以放置其他控件 --&
&LinearLayout xmlns:android=&/apk/res/android&
android:layout_width=&match_parent&
android:layout_height=&fill_parent&
android:background=&#fff&
android:orientation=&vertical& &
android:id=&@+id/textView1&
android:layout_width=&match_parent&
android:layout_height=&50dp&
android:text=&微信&
android:background=&#2B3439&
android:gravity=&center&
android:textSize=&20sp&
android:textColor=&#FFFFFF&/&
&LinearLayout
android:layout_width=&match_parent&
android:layout_height=&wrap_content&
android:layout_marginLeft=&18dp&
android:layout_marginRight=&18dp&
android:layout_marginTop=&2dp&
android:layout_marginBottom=&2dp&
android:background=&@drawable/btn_style_four_normal&&
&ImageView
android:id=&@+id/imageView1&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:src=&@drawable/sm_searchbtn&
android:layout_marginRight=&10dp&/&
android:id=&@+id/editText1&
android:layout_width=&match_parent&
android:layout_height=&35dp&
android:background=&@null&
android:ems=&10& &
&requestFocus /&
&/EditText&
&/LinearLayout&
android:id=&@+id/listView1&
android:layout_width=&match_parent&
android:paddingBottom=&50dp&
android:cacheColorHint=&#&
android:layout_height=&match_parent& &
&/ListView&
&/LinearLayout&
friend_list_item.xml文件
&?xml version=&1.0& encoding=&utf-8&?&
&!-- 这是列表项的布局文件,每一行长什么样子,修改这里 --&
&LinearLayout xmlns:android=&/apk/res/android&
android:layout_width=&fill_parent&
android:layout_height=&80dp&
android:orientation=&horizontal&
android:padding=&5dip&
android:paddingBottom=&15dp& &
&ImageView
android:id=&@+id/img&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:layout_margin=&5dp& /&
&LinearLayout
android:layout_width=&fill_parent&
android:layout_height=&wrap_content&
android:orientation=&vertical& &
&LinearLayout
android:layout_width=&fill_parent&
android:layout_height=&wrap_content&
android:orientation=&horizontal& &
android:id=&@+id/title&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:textColor=&#000&
android:textSize=&20sp& /&
android:id=&@+id/time&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:layout_marginLeft=&110dp&
android:textColor=&#000&
android:textSize=&18sp& /&
&/LinearLayout&
android:id=&@+id/info&
android:layout_width=&wrap_content&
android:layout_height=&fill_parent&
android:layout_marginTop=&3dp&
android:textColor=&#000&
android:textSize=&15sp& /&
&/LinearLayout&
&/LinearLayout&
WeixinActivity.java文件
package com.app.
import java.util.ArrayL
import java.util.HashM
import java.util.L
import com.app.wexin.R;
import android.app.A
import android.app.AlertD
import android.content.C
import android.content.DialogI
import android.content.I
import android.os.B
import android.view.LayoutI
import android.view.V
import android.view.ViewG
import android.widget.BaseA
import android.widget.B
import android.widget.ImageV
import android.widget.ListV
import android.widget.TextV
public class WeixinActivity extends Activity {
private ImageV
private List&HashMap&String, Object&& mD
private ListView listV
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.friend_list);
mData = getData();//为刚才的变量赋值
MyAdapter adapter = new MyAdapter(this);//创建一个适配器
listView = (ListView) findViewById(R.id.listView1);//实例化ListView
listView.setAdapter(adapter);//为ListView控件绑定适配器
/** 自定义适配器 */
public class MyAdapter extends BaseAdapter {
private LayoutInflater mI// 动态布局映射
public MyAdapter(Context context) {
this.mInflater = LayoutInflater.from(context);
// 决定ListView有几行可见
public int getCount() {
return mData.size();// ListView的条目数
public Object getItem(int arg0) {
public long getItemId(int arg0) {
public View getView(int position, View convertView, ViewGroup parent) {
convertView = mInflater.inflate(R.layout.friend_list_item, null);//根据布局文件实例化view
TextView title = (TextView) convertView.findViewById(R.id.title);//找某个控件
title.setText(mData.get(position).get(&title&).toString());//给该控件设置数据(数据从集合类中来)
TextView time = (TextView) convertView.findViewById(R.id.time);//找某个控件
time.setText(mData.get(position).get(&time&).toString());//给该控件设置数据(数据从集合类中来)
TextView info = (TextView) convertView.findViewById();
info.setText(mData.get(position).get(&info&).toString());
img = (ImageView) convertView.findViewById(R.id.img);
img.setBackgroundResource((Integer) mData.get(position).get(&img&));
return convertV
// 初始化一个List
private List&HashMap&String, Object&& getData() {
// 新建一个集合类,用于存放多条数据
ArrayList&HashMap&String, Object&& list = new ArrayList&HashMap&String, Object&&();
HashMap&String, Object& map =
for (int i = 1; i &= 40; i++) {
map = new HashMap&String, Object&();
map.put(&title&, &人物& + i);
map.put(&time&, &9月20日&);
map.put(&info&, &我通过了你的好友验证请求&);
map.put(&img&, R.drawable.pic_person);
list.add(map);
public void showInfo(int position){
getData();
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:505581次
积分:6481
积分:6481
排名:第2669名
原创:128篇
转载:16篇
评论:256条
文章:16篇
阅读:1235361808人阅读
Android小知识点(119)
原创(60)
& & & & &项目中用到一个内部复杂布局的listview,每个item中都有动态的子item,相当于listview的item中还有listview的样式。刚开始做的思路是,用一个listview,然后item中加个LinearLayout,然后代码动态的生成子item view 添加在其中,希望这样的表述大家能明白,按照这样的思路做好之后发现快速滑动的时候,一卡一顿,实在不能直视,在配置低点的机器上更是不能看。
但是因为赶进度一直没有优化,现在回头看下,虽然已经用了viewHolder但是listview缓冲的机制完全没有发挥作用,因为每个item show的时候都需要removeAll 子item,然后再添加一遍,绘制的时间太长,造成了卡顿。
怎么解决这个问题尼?
刚好google在support v7推出了recyclerView,有着更好的缓存优化机制,我如获救星,赶紧将listview换成了recyclerView,但是效果不尽人意,没有我想象中的效率提升,仔细想了想,recycleView只是针对listView的多type情况做了优化,而实际需求中还是在item中动态的生成item,没有用到recyclerView的优势。
那么自然下面想到的就是干掉动态生成的Item部分,把数据拆分成一个一个的listview item。但是又担心这样的工作量会不会很大,实际抽象过程中发现很容易,就把原来一个model数据拆分成了7个不同类型的model,getView的时候先通过postion 获取当前model的type,然后返回不同的View item,很简单的就把原来只有一种item的listview拆分成了一个有7种类型Item的listView。跑起来之后,速度哗哗的,感觉就更一个item的一样。
listView支持多种类型的Item时候还有个坑:继承BaseAdapter的时候必须复写下面两个方法
//滑动ListView的时候,第一个item消失之后,进入屏幕的item类型必须通过&span style=&font-family: Arial, Helvetica, sans-&&getItemViewType符合类型才会被复用,否则创建新的item类型,当然这些的前提是你必须使用了listView的缓存tag&/span&
public int getItemViewType(int position) {
return super.getItemViewType(position);
//默认这个方法返回1,所有有几种类型必须告诉listView,listView就会创建几个不同类型的队列
public int getViewTypeCount() {
return super.getViewTypeCount();
这个时候,既然动态生成子item的机制已经被干掉了,我又想到了recyclerView,如果用recyclerView会不会比ListView更优尼?说干就干,10分钟我已经完成了替换(思路有了我搬砖的效率还是很快的),跑起来之后,果然唰唰的(其实肉眼已经很难分辨出来和listView的区别了)。但是跟着google走应该不会错,他自己说的:
The&&widget
is a more advanced and flexible version of&.
This widget is a container for displaying large data sets that can be scrolled very efficiently by maintaining a limited number of views. Use the&widget
when you have data collections whose elements change at runtime based on user action or network events.
希望能帮助到有类似需求的同学:
ListView中有复杂布局,尤其是有动态生成的布局的子布局的,可以考虑一下将原来的Item拆分成不同的类型,然后使用recyclerView。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:375888次
积分:5573
积分:5573
排名:第3432名
原创:151篇
转载:104篇
评论:220条
(4)(3)(3)(1)(3)(4)(3)(3)(2)(1)(1)(2)(2)(5)(5)(6)(10)(4)(1)(4)(12)(2)(5)(7)(15)(4)(10)(15)(18)(7)(11)(19)(25)(35)(5)Android ListView实现类似朋友圈的复杂布局 - 博客频道 - CSDN.NET
nightyk的专栏
开发中时常会遇到用ListView实现类似朋友圈列表的复杂布局,如果一个条信息即为ListView中一项时,那么单个布局的结构会变的很复杂,也会影响列表滚动的流畅性。由于Adapter可以使用多种布局,所以这里采用的方式是将单个信息的布局拆分为多个ListView的item来达到优化的目的。借用中的一张图
先上一张效果图:
这里将一条信息的页面拆分为4个:title, body, image, bottom。
item_title.xml
&?xml version=&1.0& encoding=&utf-8&?&
&LinearLayout xmlns:android=&/apk/res/android&
android:orientation=&vertical&
android:layout_width=&match_parent&
android:layout_height=&match_parent&
android:background=&@android:color/white&
android:padding=&5dp&&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:text=&New Text&
android:id=&@+id/title&/&
&/LinearLayout&
item_body.xml
&?xml version=&1.0& encoding=&utf-8&?&
&LinearLayout xmlns:android=&/apk/res/android&
android:orientation=&vertical&
android:layout_width=&match_parent&
android:layout_height=&match_parent&
android:padding=&5dp&
android:background=&@android:color/white&&
android:layout_width=&wrap_content&
android:layout_height=&wrap_content&
android:textAppearance=&?android:attr/textAppearanceLarge&
android:text=&Large Text&
android:lines=&4&
android:id=&@+id/body&/&
&/LinearLayout&
item_image.xml
&?xml version=&1.0& encoding=&utf-8&?&
&LinearLayout xmlns:android=&/apk/res/android&
android:orientation=&vertical&
android:layout_width=&match_parent&
android:gravity=&center&
android:background=&@android:color/white&
android:layout_height=&match_parent&&
&ImageView
android:layout_width=&100dp&
android:layout_height=&100dp&
android:src=&@mipmap/ic_launcher&
android:id=&@+id/image&/&
&/LinearLayout&
item_bottom.xml
&?xml version=&1.0& encoding=&utf-8&?&
&LinearLayout xmlns:android=&/apk/res/android&
android:orientation=&vertical&
android:layout_width=&match_parent&
android:layout_height=&match_parent&&
android:layout_width=&match_parent&
android:layout_height=&2dp&/&
&LinearLayout
android:orientation=&horizontal&
android:layout_width=&match_parent&
android:layout_height=&wrap_content&
android:background=&@android:color/white&&
&ImageButton
android:layout_width=&0dp&
android:layout_weight=&1&
android:layout_height=&48dp&
android:src=&@android:drawable/ic_media_play&
android:background=&@android:color/transparent&
android:id=&@+id/button1&/&
&ImageButton
android:layout_width=&0dp&
android:layout_weight=&1&
android:layout_height=&48dp&
android:src=&@android:drawable/ic_media_play&
android:background=&@android:color/transparent&
android:id=&@+id/button2&/&
&ImageButton
android:layout_width=&0dp&
android:layout_weight=&1&
android:layout_height=&48dp&
android:src=&@android:drawable/ic_media_play&
android:background=&@android:color/transparent&
android:id=&@+id/button3&/&
&/LinearLayout&
android:layout_width=&match_parent&
android:layout_height=&10dp&/&
&/LinearLayout&
定义需要显示消息类News。
public class News {
public static final int TEXT = 1;
public static final int IMAGE = 2;
private int newsId;
private int imageS
public News(int newsId, int type, String title, String body, int imageSource) {
this.newsId = newsId;
this.type =
this.title =
this.body =
this.imageSource = imageS
//////省略get,set方法
由于需要将一条News拆分为多条ListView的item,所以定义一个Item类。ListView列表的中的每一条即为此item类。
public class Item {
public static final int TITLE=0;
public static final int IMAGE=1;
public static final int BODY=2;
public static final int BOTTOM=3;
private int newsT//News类型
private int newsId;
private int styleT//显示类型
private int imageS
//////省略get,set方法
在显示之前,要将News类转换成多个Item类。这里定义一个转换工具类。
public class NewsToItem {
public static ArrayList&Item& newsToItems(List&News& list) {
ArrayList&Item& items = new ArrayList&Item&();
for (News news : list) {
items.add(createTitle(news));
if (News.TEXT == news.getType()) {
items.add(createBody(news));
items.add(createImage(news));
items.add(createBottom(news));
private static Item createTitle(News news) {
Item item = new Item();
item.setNewsType(news.getType());
item.setStyleType(Item.TITLE);
item.setText(news.getTitle());
private static Item createImage(News news) {
Item item = new Item();
item.setNewsType(news.getType());
item.setStyleType(Item.IMAGE);
item.setImageSource(news.getImageSource());
private static Item createBody(News news) {
Item item = new Item();
item.setNewsType(news.getType());
item.setStyleType(Item.BODY);
item.setText(news.getBody());
private static Item createBottom(News news) {
Item item = new Item();
item.setNewsType(news.getType());
item.setStyleType(Item.BOTTOM);
之后定义Adapter。
public class NewsAdapter extends BaseAdapter {
private ArrayList&Item&
private LayoutInflater mI
public NewsAdapter(Context context) {
list = new ArrayList&Item&();
mInflater = LayoutInflater.from(context);
public int getCount() {
return list.size();
public Item getItem(int position) {
return list.get(position);
public long getItemId(int position) {
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder =
int type = getItemViewType(position);
if (null == convertView) {
viewHolder = new ViewHolder();
switch (type) {
case Item.TITLE:
convertView = mInflater.inflate(R.layout.item_title, parent, false);
viewHolder.tvTitle = (TextView) convertView.findViewById(R.id.title);
case Item.BODY:
convertView = mInflater.inflate(R.layout.item_body, parent, false);
viewHolder.tvBody = (TextView) convertView.findViewById(R.id.body);
case Item.IMAGE:
convertView = mInflater.inflate(R.layout.item_image, parent, false);
viewHolder.ivImage = (ImageView) convertView.findViewById(R.id.image);
case Item.BOTTOM:
convertView = mInflater.inflate(R.layout.item_bottom, parent, false);
if (null != convertView) {
convertView.setTag(viewHolder);
viewHolder = (ViewHolder) convertView.getTag();
Item item = list.get(position);
switch (type) {
case Item.TITLE:
viewHolder.tvTitle.setText(item.getText());
case Item.BODY:
viewHolder.tvBody.setText(item.getText());
case Item.IMAGE:
viewHolder.ivImage.setImageResource(item.getImageSource());
return convertV
public int getItemViewType(int position) {
return list.get(position).getStyleType();
public int getViewTypeCount() {
public void add(Item item){
list.add(item);
public void addAll(List&Item& items){
list.addAll(items);
static class ViewHolder {
TextView tvT
TextView tvB
ImageView ivI
View bottomV
最后是Activity。
public class MainActivity extends ListActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getListView().setDividerHeight(0);
getListView().setPadding(10, 10, 10, 10);
ArrayList&News& newses = new ArrayList&&();
newses.add(new News(0, News.TEXT, &title1&, &This is News 1.&, 0));
newses.add(new News(1, News.TEXT, &title2&, &This is News 2.&, 0));
newses.add(new News(2, News.IMAGE, &title3&, &&, android.R.drawable.ic_menu_camera));
newses.add(new News(3, News.IMAGE, &title4&, &&, android.R.drawable.ic_menu_call));
newses.add(new News(4, News.TEXT, &title5&, &This is News 5.&, 0));
newses.add(new News(5, News.IMAGE, &title6&, &&, android.R.drawable.ic_menu_gallery));
newses.add(new News(6, News.TEXT, &title7&, &This is News 6.&, 0));
newses.add(new News(7, News.TEXT, &title8&, &This is News 7.&, 0));
newses.add(new News(8, News.IMAGE, &title9&, &&, android.R.drawable.ic_menu_compass));
NewsAdapter adapter = new NewsAdapter(this);
adapter.addAll(NewsToItem.newsToItems(newses));
setListAdapter(adapter);
实际的项目中,布局的复杂程度可能会远远高于本例,但是实现的基本思路应该是一样的。
排名:千里之外&&&&ListView复杂布局Demo
ListView复杂布局Demo
本Demo是使用简单的ListView控件实现复杂的布局,其中每个Item可包括Button点击事件,并实现Button点击事件和Listview的ItemClick事件共存的问题。
本Demo还可拓展为Listview多选 进而实现批量处理功能,但是该功能为实现事件,只实现多选效果需要自行编程实现选中的Item。
另外:本demo有一个bug,我还不知道怎么解决,就是在Android2.3系统下会出现点击区域不明确的问题,希望有知道原因的能帮忙解决分享一下。
Createby: gcf
mail: @ qq.com
若举报审核通过,可奖励20下载分
被举报人:
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:
VIP下载&&免积分60元/年(1200次)
您可能还需要
移动开发下载排行

我要回帖

更多关于 listview 复杂item 的文章

 

随机推荐