Android ListView点击Item展开隐藏项,单个展开,多个展开
2017-07-27 15:14
453 查看
版权声明:^_^ 尊重原创,共享知识,转载请注明"_程序猿大人_"http://blog.csdn.net/a_running_wolf
我做了一些修改
手机屏幕毕竟有限,当我们要显示较多数据时便不得不舍去一些次要信息,将主要信息优先显示,也使显示效果更加简洁美观。遇到类似的需求,我们使用最多的就是
ListView ,而如果每次点击一个 Item 都要跳转到下一页查看详情,查看另一个还要返回列表重新进入另一条详情,使得操作繁琐体验降低。此时可隐藏和展开 Item 的 ListView 便应运而生,这不是一个新的控件,只是我们灵活使用造出来的用法,下边我就来实现 ListView 点击 Item 展开隐藏项,包括列表单项展开、多项展开、复杂布局展开的实现。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------------
Activity 的布局文件就不看了,只有一个 ListView。我们看 OneExpandAdapter.java:先看
Adapter 用到的布局样式:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
20000
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/shape2"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/layout_showArea"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp" >
<TextView
android:id="@+id/tv_phoneType"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="HTC M8"
android:textColor="#162834"
android:textSize="25sp" />
<TextView
android:id="@+id/tv_discount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:text="9"
android:textColor="#F75252"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="折"
android:textColor="#F75252"
android:textSize="15sp" />
<TextView
android:id="@+id/tv_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="100dp"
android:text="2000"
android:textColor="#F75252"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="¥"
android:textColor="#767171"
android:textSize="15sp" />
</LinearLayout>
<RelativeLayout
android:id="@+id/layout_hideArea"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp" >
<TextView
android:id="@+id/tv_timeNote"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/tv_time"
android:text="活动截止时间:"
android:textColor="#162834"
android:textSize="12sp" />
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/tv_timeNote"
android:text="2016.02.10"
android:textColor="#F09BED"
android:textSize="15sp" />
<TextView
android:id="@+id/tv_numNote"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_timeNote"
android:layout_marginTop="10dp"
android:text="库存剩余:"
android:textColor="#162834"
android:textSize="12sp" />
<TextView
android:id="@+id/tv_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/tv_numNote"
android:layout_below="@id/tv_time"
android:layout_toRightOf="@id/tv_numNote"
android:gravity="bottom"
android:text="888"
android:textColor="#F09BED"
android:textSize="15sp" />
<ImageView
android:id="@+id/img_icon"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:src="@drawable/red_packet" />
<Button
android:id="@+id/btn_buy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_num"
android:padding="4dp"
android:textSize="24sp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/select_btn"
android:text="立即抢购" />
</RelativeLayout>
</LinearLayout>
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
看 Adapter 的代码(总体都还是常规用法,本次用到的逻辑都有注释):
/**
* 点击item展开隐藏部分,再次点击收起
* 只可展开一条记录
*
* @author WangJ
* @date 2016.01.31
*/
public class OneExpandAdapter extends BaseAdapter {
private Context context;
private ArrayList<HashMap<String, String>> list;
private int currentItem = -1; //用于记录点击的 Item 的 position,是控制 item 展开的核心
public OneExpandAdapter(Context context,
ArrayList<HashMap<String, String>> list) {
super();
this.context = context;
this.list = list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(
R.layout.item_2, parent, false);
holder = new ViewHolder();
holder.showArea = (LinearLayout) convertView.findViewById(R.id.layout_showArea);
holder.tvPhoneType = (TextView) convertView
.findViewById(R.id.tv_phoneType);
holder.tvDiscount = (TextView) convertView
.findViewById(R.id.tv_discount);
holder.tvPrice = (TextView) convertView
.findViewById(R.id.tv_price);
holder.tvTime = (TextView) convertView
.findViewById(R.id.tv_time);
holder.tvNum = (TextView) convertView
.findViewById(R.id.tv_num);
holder.btnBuy = (Button) convertView
.findViewById(R.id.btn_buy);
holder.hideArea = (RelativeLayout) convertView.findViewById(R.id.layout_hideArea);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
HashMap<String, String> item = list.get(position);
// 注意:我们在此给响应点击事件的区域(我的例子里是 showArea 的线性布局)添加Tag,为了记录点击的 position,我们正好用 position 设置 Tag
holder.showArea.setTag(position);
holder.tvPhoneType.setText(item.get("phoneType"));
holder.tvDiscount.setText(item.get("discount"));
holder.tvPrice.setText(item.get("price"));
holder.tvTime.setText(item.get("time"));
holder.tvNum.setText(item.get("num"));
//根据 currentItem 记录的点击位置来设置"对应Item"的可见性(在list依次加载列表数据时,每加载一个时都看一下是不是需改变可见性的那一条)
if (currentItem == position) {
holder.hideArea.setVisibility(View.VISIBLE);
} else {
holder.hideArea.setVisibility(View.GONE);
}
holder.showArea.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
//用 currentItem 记录点击位置
int tag = (Integer) view.getTag();
if (tag == currentItem) { //再次点击
currentItem = -1; //给 currentItem 一个无效值
} else {
currentItem = tag;
}
//通知adapter数据改变需要重新加载
notifyDataSetChanged(); //必须有的一步
}
});
holder.tvPhoneType.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(context, "hehe", Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
private static class ViewHolder {
private LinearLayout showArea;
private TextView tvPhoneType;
private TextView tvDiscount;
private TextView tvPrice;
private TextView tvTime;
private TextView tvNum;
private Button btnBuy;
private RelativeLayout hideArea;
}
}
我们只是给特定组件 setTag(int position),根据点击的 View 记录下这个 position,在 getView() 中判断当前加载 View 是 position 是不是和记录的 position 相等来进行特定组件的可见性设置即可。
这里我们需要明白:我们平时对 ListView 做的最多的操作就是 setOnItemClickListener,这个操作一般都是在 Activity 中进行的,此时响应区域是 Item 整体,不管你点击 Item 的哪个角落都会响应。而对于每个 Item 中子控件的事件监听(区别于整个Item,比如说 Item 中的按钮、输入框等等)都是在适配器类中添加,此时只有点击添加监听的子控件区域才会响应,相当于每个 Item 中的该控件都添加了监听。OnClick 的响应优先级:子控件(元控件)>
父布局(但是不像 onTouch 事件有 Boolean 返回值那样,OnClick 事件是没有返回值的,即是“阻断式式响应”,不会再响应它所归属的上层控件)。
就不一一的列代码了,多项展开,表格展开的下载地址:http://download.csdn.net/detail/zhanghuaiwang/9912624
我做了一些修改
手机屏幕毕竟有限,当我们要显示较多数据时便不得不舍去一些次要信息,将主要信息优先显示,也使显示效果更加简洁美观。遇到类似的需求,我们使用最多的就是
ListView ,而如果每次点击一个 Item 都要跳转到下一页查看详情,查看另一个还要返回列表重新进入另一条详情,使得操作繁琐体验降低。此时可隐藏和展开 Item 的 ListView 便应运而生,这不是一个新的控件,只是我们灵活使用造出来的用法,下边我就来实现 ListView 点击 Item 展开隐藏项,包括列表单项展开、多项展开、复杂布局展开的实现。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
一、单项展开
OneExpandActivity 中就是模拟一些数据,使用 OneExpandAdapter 适配器加载:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
private void requestData() { ArrayList<HashMap<String, String>> datas = new ArrayList<HashMap<String,String>>(); for(int i = 1; i <= 10; i++){ HashMap<String, String> item = new HashMap<String, String>(); item.put("phoneType", "HTC-M" + i + ""); item.put("discount", "9"); item.put("price", (2000 + i) + ""); item.put("time", "2016020" + i); item.put("num", (300 - i) + ""); datas.add(item); } ListView lvProduct = (ListView) findViewById(R.id.lv_products); OneExpandAdapter adapter = new OneExpandAdapter(this, datas); lvProduct.setAdapter(adapter); }
-------------------------------------------------------------------------------------------------------------------------------
Activity 的布局文件就不看了,只有一个 ListView。我们看 OneExpandAdapter.java:先看
Adapter 用到的布局样式:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
20000
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/shape2"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/layout_showArea"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp" >
<TextView
android:id="@+id/tv_phoneType"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="HTC M8"
android:textColor="#162834"
android:textSize="25sp" />
<TextView
android:id="@+id/tv_discount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:text="9"
android:textColor="#F75252"
android:textSize="15sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="折"
android:textColor="#F75252"
android:textSize="15sp" />
<TextView
android:id="@+id/tv_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="100dp"
android:text="2000"
android:textColor="#F75252"
android:textSize="20sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="¥"
android:textColor="#767171"
android:textSize="15sp" />
</LinearLayout>
<RelativeLayout
android:id="@+id/layout_hideArea"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp" >
<TextView
android:id="@+id/tv_timeNote"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/tv_time"
android:text="活动截止时间:"
android:textColor="#162834"
android:textSize="12sp" />
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/tv_timeNote"
android:text="2016.02.10"
android:textColor="#F09BED"
android:textSize="15sp" />
<TextView
android:id="@+id/tv_numNote"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_timeNote"
android:layout_marginTop="10dp"
android:text="库存剩余:"
android:textColor="#162834"
android:textSize="12sp" />
<TextView
android:id="@+id/tv_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/tv_numNote"
android:layout_below="@id/tv_time"
android:layout_toRightOf="@id/tv_numNote"
android:gravity="bottom"
android:text="888"
android:textColor="#F09BED"
android:textSize="15sp" />
<ImageView
android:id="@+id/img_icon"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:src="@drawable/red_packet" />
<Button
android:id="@+id/btn_buy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/tv_num"
android:padding="4dp"
android:textSize="24sp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:background="@drawable/select_btn"
android:text="立即抢购" />
</RelativeLayout>
</LinearLayout>
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
看 Adapter 的代码(总体都还是常规用法,本次用到的逻辑都有注释):
/**
* 点击item展开隐藏部分,再次点击收起
* 只可展开一条记录
*
* @author WangJ
* @date 2016.01.31
*/
public class OneExpandAdapter extends BaseAdapter {
private Context context;
private ArrayList<HashMap<String, String>> list;
private int currentItem = -1; //用于记录点击的 Item 的 position,是控制 item 展开的核心
public OneExpandAdapter(Context context,
ArrayList<HashMap<String, String>> list) {
super();
this.context = context;
this.list = list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(
R.layout.item_2, parent, false);
holder = new ViewHolder();
holder.showArea = (LinearLayout) convertView.findViewById(R.id.layout_showArea);
holder.tvPhoneType = (TextView) convertView
.findViewById(R.id.tv_phoneType);
holder.tvDiscount = (TextView) convertView
.findViewById(R.id.tv_discount);
holder.tvPrice = (TextView) convertView
.findViewById(R.id.tv_price);
holder.tvTime = (TextView) convertView
.findViewById(R.id.tv_time);
holder.tvNum = (TextView) convertView
.findViewById(R.id.tv_num);
holder.btnBuy = (Button) convertView
.findViewById(R.id.btn_buy);
holder.hideArea = (RelativeLayout) convertView.findViewById(R.id.layout_hideArea);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
HashMap<String, String> item = list.get(position);
// 注意:我们在此给响应点击事件的区域(我的例子里是 showArea 的线性布局)添加Tag,为了记录点击的 position,我们正好用 position 设置 Tag
holder.showArea.setTag(position);
holder.tvPhoneType.setText(item.get("phoneType"));
holder.tvDiscount.setText(item.get("discount"));
holder.tvPrice.setText(item.get("price"));
holder.tvTime.setText(item.get("time"));
holder.tvNum.setText(item.get("num"));
//根据 currentItem 记录的点击位置来设置"对应Item"的可见性(在list依次加载列表数据时,每加载一个时都看一下是不是需改变可见性的那一条)
if (currentItem == position) {
holder.hideArea.setVisibility(View.VISIBLE);
} else {
holder.hideArea.setVisibility(View.GONE);
}
holder.showArea.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
//用 currentItem 记录点击位置
int tag = (Integer) view.getTag();
if (tag == currentItem) { //再次点击
currentItem = -1; //给 currentItem 一个无效值
} else {
currentItem = tag;
}
//通知adapter数据改变需要重新加载
notifyDataSetChanged(); //必须有的一步
}
});
holder.tvPhoneType.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(context, "hehe", Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
private static class ViewHolder {
private LinearLayout showArea;
private TextView tvPhoneType;
private TextView tvDiscount;
private TextView tvPrice;
private TextView tvTime;
private TextView tvNum;
private Button btnBuy;
private RelativeLayout hideArea;
}
}
我们只是给特定组件 setTag(int position),根据点击的 View 记录下这个 position,在 getView() 中判断当前加载 View 是 position 是不是和记录的 position 相等来进行特定组件的可见性设置即可。
这里我们需要明白:我们平时对 ListView 做的最多的操作就是 setOnItemClickListener,这个操作一般都是在 Activity 中进行的,此时响应区域是 Item 整体,不管你点击 Item 的哪个角落都会响应。而对于每个 Item 中子控件的事件监听(区别于整个Item,比如说 Item 中的按钮、输入框等等)都是在适配器类中添加,此时只有点击添加监听的子控件区域才会响应,相当于每个 Item 中的该控件都添加了监听。OnClick 的响应优先级:子控件(元控件)>
父布局(但是不像 onTouch 事件有 Boolean 返回值那样,OnClick 事件是没有返回值的,即是“阻断式式响应”,不会再响应它所归属的上层控件)。
就不一一的列代码了,多项展开,表格展开的下载地址:http://download.csdn.net/detail/zhanghuaiwang/9912624
相关文章推荐
- android listView 全部展开,并且点击Item有效,可以用scrollView包裹,实现整体滑动
- android的ListView点击item使item展开的做法
- Android--ListView点击Item展开的实现
- android listview的item的展开与隐藏
- ListView点击Item展开隐藏项(单项展开、多项展开、复杂布局时的展开处理)
- 点击ListView的item展开隐藏的view
- Android 禁止ExpandableListView组的点击展开或隐藏事件,让所有列表都展开
- android实现Listview的点击展开和隐藏功能
- android的ListView点击item使item展开的做法
- android之listview点击item展开内容
- Android基础:listview的item点击事件会使里面的Button也出现按压的效果
- Android菜鸟练习第二十三课 ListView嵌套GridView,GridView中item无法点击
- Android ListView的Item点击事件和Item里控件点击事件冲突问题解决
- android捕获ListView中每个item点击事件
- android ListView item中添加checkbox之后点击无效的解决办法
- android之listview的item不可点击
- Android开发笔记之listView的item事件点击失效
- android中ListView点击和ListView的item里面的button或ImageView不能同时生效的解决
- Android_ListView_去掉滑动时的黑色背景和点击某个item时的橙黄色背景
- android 调用第三方软件打开pdf文件》 ListView点击item