首先我们还是来看一些案例,还是拿搜狐新闻客户端,因为我天天上下班没事爱看这个东东,上班又没时间看新闻,上下班路途之余浏览下新闻打发时间嘛.

         

看这个效果挺棒吧,其实实现起来也不难,我简单说明下.

首先我们用到的控件是:ExpandableListView

布局文件:

[java] view
plain
copy

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent" >
  5. <!--
  6. android:groupIndicator="@null" 取消默认图片
  7. android:childIndicatorLeft 设置孩子左边间距
  8. android:dividerHeight 这个高度一定要设置,不然显示不出来分割线,估计默认为0 吧
  9. android:childDivider="@drawable/child_bg" 这个直接引color,或者图片会导致整个孩子背景都为这个颜色  ,不知道原因,如果有谁知道,请Give me say.
  10. -->
  11. <ExpandableListView
  12. android:id="@+id/expandablelist"
  13. android:layout_width="match_parent"
  14. android:layout_height="match_parent"
  15. android:cacheColorHint="@null"
  16. android:childDivider="@drawable/child_bg"
  17. android:childIndicatorLeft="0dp"
  18. android:divider="@color/Grey"
  19. android:dividerHeight="1dp"
  20. android:groupIndicator="@null"
  21. android:scrollbarAlwaysDrawHorizontalTrack="true" >
  22. </ExpandableListView>
  23. </RelativeLayout>

MyexpandableListAdapter.java

[java] view
plain
copy

  1. /***
  2. * 数据源
  3. *
  4. * @author Administrator
  5. *
  6. */
  7. class MyexpandableListAdapter extends BaseExpandableListAdapter {
  8. private Context context;
  9. private LayoutInflater inflater;
  10. public MyexpandableListAdapter(Context context) {
  11. this.context = context;
  12. inflater = LayoutInflater.from(context);
  13. }
  14. // 返回父列表个数
  15. @Override
  16. public int getGroupCount() {
  17. return groupList.size();
  18. }
  19. // 返回子列表个数
  20. @Override
  21. public int getChildrenCount(int groupPosition) {
  22. return childList.get(groupPosition).size();
  23. }
  24. @Override
  25. public Object getGroup(int groupPosition) {
  26. return groupList.get(groupPosition);
  27. }
  28. @Override
  29. public Object getChild(int groupPosition, int childPosition) {
  30. return childList.get(groupPosition).get(childPosition);
  31. }
  32. @Override
  33. public long getGroupId(int groupPosition) {
  34. return groupPosition;
  35. }
  36. @Override
  37. public long getChildId(int groupPosition, int childPosition) {
  38. return childPosition;
  39. }
  40. @Override
  41. public boolean hasStableIds() {
  42. return true;
  43. }
  44. @Override
  45. public View getGroupView(int groupPosition, boolean isExpanded,
  46. View convertView, ViewGroup parent) {
  47. GroupHolder groupHolder = null;
  48. if (convertView == null) {
  49. groupHolder = new GroupHolder();
  50. convertView = inflater.inflate(R.layout.group, null);
  51. groupHolder.textView = (TextView) convertView
  52. .findViewById(R.id.group);
  53. groupHolder.imageView = (ImageView) convertView
  54. .findViewById(R.id.image);
  55. groupHolder.textView.setTextSize(15);
  56. convertView.setTag(groupHolder);
  57. } else {
  58. groupHolder = (GroupHolder) convertView.getTag();
  59. }
  60. groupHolder.textView.setText(getGroup(groupPosition).toString());
  61. if (isExpanded)// ture is Expanded or false is not isExpanded
  62. groupHolder.imageView.setImageResource(R.drawable.expanded);
  63. else
  64. groupHolder.imageView.setImageResource(R.drawable.collapse);
  65. return convertView;
  66. }
  67. @Override
  68. public View getChildView(int groupPosition, int childPosition,
  69. boolean isLastChild, View convertView, ViewGroup parent) {
  70. if (convertView == null) {
  71. convertView = inflater.inflate(R.layout.item, null);
  72. }
  73. TextView textView = (TextView) convertView.findViewById(R.id.item);
  74. textView.setTextSize(13);
  75. textView.setText(getChild(groupPosition, childPosition).toString());
  76. return convertView;
  77. }
  78. @Override
  79. public boolean isChildSelectable(int groupPosition, int childPosition) {
  80. return true;
  81. }
  82. }
  83. @Override
  84. public boolean onGroupClick(final ExpandableListView parent, final View v,
  85. int groupPosition, final long id) {
  86. return false;
  87. }

上面实现起来比较简单.相信对listview熟悉的朋友看这个一定很熟悉,无外乎就是多了个孩子.

selector_group.xml

[java] view
plain
copy

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <selector xmlns:android="http://schemas.android.com/apk/res/android">
  3. <item android:drawable="@color/Grey" android:state_pressed="true"></item>
  4. <item android:drawable="@color/Grey" android:state_selected="true"></item>
  5. <item android:drawable="@color/LightGray"></item>
  6. </selector>

selector_item.xml  同理.

效果图:

        
     

效果虽然丑了点,不过就是这么回事,至于显示group的item,还是孩子的item,你可以随意定制.

不想敲的同学,可以下载源码,稍作调整.

源码下载

/********************************LIstView模拟ExpandableListView**************************************************************/

下面我们接着看一些案例:

         

其实就是:点击listview的一个item,展开其孩子,点击另一个item,打开其孩子,关闭之前那个孩子.

这个眨一看是ExpandableListView这个东东,可是本人比较笨戳,整了好久没有弄出来,最终放弃,google下,发现有人用listview来模拟实现,也就跟着做了下.

布局文件:(后面多个隐藏text.)

[java] view
plain
copy

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="wrap_content"
  5. android:background="@color/white"
  6. android:gravity="center_vertical"
  7. android:orientation="vertical" >
  8. <RelativeLayout
  9. android:layout_width="match_parent"
  10. android:layout_height="wrap_content"
  11. android:background="@drawable/selector_group"
  12. android:gravity="center_vertical"
  13. android:orientation="horizontal"
  14. android:padding="5dp" >
  15. <TextView
  16. android:id="@+id/group"
  17. android:layout_width="wrap_content"
  18. android:layout_height="wrap_content"
  19. android:layout_centerVertical="true"
  20. android:textColor="@color/black" />
  21. <ImageView
  22. android:id="@+id/image"
  23. android:layout_width="wrap_content"
  24. android:layout_height="wrap_content"
  25. android:layout_alignParentRight="true"
  26. android:layout_centerVertical="true"
  27. android:src="@drawable/collapse" />
  28. </RelativeLayout>
  29. <TextView
  30. android:id="@+id/hint_item"
  31. android:layout_width="fill_parent"
  32. android:layout_height="wrap_content"
  33. android:gravity="center_vertical"
  34. android:padding="10dp"
  35. android:textColor="@color/black"
  36. android:visibility="gone" />
  37. </LinearLayout>

MyAdpter.java

[java] view
plain
copy

  1. /***
  2. * 数据源
  3. *
  4. * @author zhangjia
  5. *
  6. */
  7. class MyAdpter extends BaseAdapter {
  8. private Context context;
  9. private LayoutInflater inflater;
  10. private int change_index = -1;// 改变项
  11. public MyAdpter(Context context) {
  12. super();
  13. this.context = context;
  14. inflater = (LayoutInflater) context
  15. .getSystemService(context.LAYOUT_INFLATER_SERVICE);
  16. }
  17. @Override
  18. public int getCount() {
  19. return groupList.size();
  20. }
  21. @Override
  22. public Object getItem(int position) {
  23. return groupList.get(position);
  24. }
  25. @Override
  26. public long getItemId(int position) {
  27. return position;
  28. }
  29. @Override
  30. public View getView(int position, View convertView, ViewGroup parent) {
  31. GroupHolder groupHolder = null;
  32. if (convertView == null) {
  33. groupHolder = new GroupHolder();
  34. convertView = inflater.inflate(R.layout.group, null);
  35. groupHolder.textView = (TextView) convertView
  36. .findViewById(R.id.group);
  37. groupHolder.imageView = (ImageView) convertView
  38. .findViewById(R.id.image);
  39. groupHolder.hint_item = (TextView) convertView
  40. .findViewById(R.id.hint_item);
  41. convertView.setTag(groupHolder);
  42. } else {
  43. groupHolder = (GroupHolder) convertView.getTag();
  44. }
  45. groupHolder.textView.setText(groupList.get(position));
  46. groupHolder.hint_item.setText(childList.get(position));
  47. if (change_index == position)
  48. groupHolder.hint_item.setVisibility(View.VISIBLE);
  49. else
  50. groupHolder.hint_item.setVisibility(View.GONE);
  51. return convertView;
  52. }
  53. /***
  54. * 这个方法用于更改子item的状态
  55. */
  56. public void changeImageVisable(View view, int position) {
  57. // 隐藏提示
  58. if (change_index == position) {
  59. GroupHolder groupHolder = (GroupHolder) view.getTag();
  60. if (groupHolder.hint_item.getVisibility() == View.VISIBLE)
  61. groupHolder.hint_item.setVisibility(View.GONE);
  62. else
  63. groupHolder.hint_item.setVisibility(View.VISIBLE);
  64. } else {
  65. change_index = position;
  66. notifyDataSetChanged();// restart getview
  67. }
  68. }
  69. }

这个数据源很简单,只是多了个用于控制孩子隐藏与显示的方法changeImageVisable.代码很简单,相信不用过多解释.

效果:

        
     

上面模拟显示的孩子是一个textview(缺点:隐藏textview显示时候点击会影响到其父控件,大家尝试一下,不过肯定有解决办法的.),

下面我来介绍下,如果孩子是listview应该怎么办.

首先配置文件:

[java] view
plain
copy

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!-- android:descendantFocusability="blocksDescendants"这个属性就可以让父listview获取焦点 -->
  3. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="match_parent"
  5. android:layout_height="wrap_content"
  6. android:background="@color/white"
  7. android:descendantFocusability="blocksDescendants"
  8. android:gravity="center_vertical"
  9. android:orientation="vertical" >
  10. <RelativeLayout
  11. android:layout_width="match_parent"
  12. android:layout_height="wrap_content"
  13. android:background="@drawable/selector_group"
  14. android:gravity="center_vertical"
  15. android:orientation="horizontal"
  16. android:padding="5dp" >
  17. <TextView
  18. android:id="@+id/group"
  19. android:layout_width="wrap_content"
  20. android:layout_height="wrap_content"
  21. android:layout_centerVertical="true"
  22. android:text="精品推荐"
  23. android:textColor="@color/black" />
  24. <ImageView
  25. android:id="@+id/image"
  26. android:layout_width="wrap_content"
  27. android:layout_height="wrap_content"
  28. android:layout_alignParentRight="true"
  29. android:layout_centerVertical="true"
  30. android:src="@drawable/collapse" />
  31. </RelativeLayout>
  32. <ListView
  33. android:id="@+id/hint_item"
  34. android:layout_width="fill_parent"
  35. android:layout_height="wrap_content"
  36. android:gravity="center_vertical"
  37. android:textColor="@color/black" />
  38. </LinearLayout>
[java] view
plain
copy

  1. /***
  2. * InitData
  3. */
  4. void InitData() {
  5. groupList = new ArrayList<String>();
  6. groupList.add("Ios");
  7. groupList.add("Android");
  8. groupList.add("Window");
  9. childList = new ArrayList<ArrayList<String>>();
  10. for (int i = 0; i < groupList.size(); i++) {
  11. ArrayList<String> childTemp;
  12. if (i == 0) {
  13. childTemp = new ArrayList<String>();
  14. childTemp.add("iphone 4");
  15. childTemp.add("iphone 5");
  16. } else if (i == 1) {
  17. childTemp = new ArrayList<String>();
  18. childTemp.add("Anycall");
  19. childTemp.add("HTC");
  20. childTemp.add("Motorola");
  21. } else {
  22. childTemp = new ArrayList<String>();
  23. childTemp.add("Lumia 800C ");
  24. }
  25. childList.add(childTemp);
  26. }
  27. }
[java] view
plain
copy

  1. /***
  2. * 父数据源
  3. *
  4. * @author zhangjia
  5. *
  6. */
  7. class MyAdpter extends BaseAdapter {
  8. private Context context;
  9. private LayoutInflater inflater;
  10. private int change_index = -1;// 改变项
  11. public MyAdpter(Context context) {
  12. super();
  13. this.context = context;
  14. inflater = (LayoutInflater) context
  15. .getSystemService(context.LAYOUT_INFLATER_SERVICE);
  16. }
  17. @Override
  18. public int getCount() {
  19. return groupList.size();
  20. }
  21. @Override
  22. public Object getItem(int position) {
  23. return groupList.get(position);
  24. }
  25. @Override
  26. public long getItemId(int position) {
  27. return position;
  28. }
  29. @Override
  30. public View getView(final int position, View convertView,
  31. ViewGroup parent) {
  32. GroupHolder groupHolder = null;
  33. if (convertView == null) {
  34. groupHolder = new GroupHolder();
  35. convertView = inflater.inflate(R.layout.group_item, null);
  36. groupHolder.textView = (TextView) convertView
  37. .findViewById(R.id.group);
  38. groupHolder.imageView = (ImageView) convertView
  39. .findViewById(R.id.image);
  40. groupHolder.hint_item = (ListView) convertView
  41. .findViewById(R.id.hint_item);
  42. convertView.setTag(groupHolder);
  43. } else {
  44. groupHolder = (GroupHolder) convertView.getTag();
  45. }
  46. groupHolder.textView.setText(groupList.get(position));
  47. groupHolder.hint_item.setAdapter(getListView(childList
  48. .get(position)));
  49. groupHolder.hint_item
  50. .setOnItemClickListener(new OnItemClickListener() {
  51. @Override
  52. public void onItemClick(AdapterView<?> parent,
  53. View view, int position_id, long id) {
  54. Toast.makeText(context,
  55. childList.get(position).get(position_id), 1)
  56. .show();
  57. }
  58. });
  59. // 动态设置listview 的高度
  60. setListViewHeightBaseOnChildren(groupHolder.hint_item);
  61. if (change_index == position) {
  62. groupHolder.hint_item.setVisibility(View.VISIBLE);
  63. groupHolder.imageView.setImageResource(R.drawable.expanded);
  64. }
  65. else {
  66. groupHolder.hint_item.setVisibility(View.GONE);
  67. groupHolder.imageView.setImageResource(R.drawable.collapse);
  68. }
  69. return convertView;
  70. }
  71. /***
  72. * 这个方法用于更改子item的状态
  73. */
  74. public void changeImageVisable(View view, int position) {
  75. // 隐藏提示
  76. if (change_index == position) {
  77. GroupHolder groupHolder = (GroupHolder) view.getTag();
  78. if (groupHolder.hint_item.getVisibility() == View.VISIBLE)
  79. groupHolder.hint_item.setVisibility(View.GONE);
  80. else
  81. groupHolder.hint_item.setVisibility(View.VISIBLE);
  82. } else {
  83. change_index = position;
  84. notifyDataSetChanged();// restart getview
  85. }
  86. }
  87. }

上面代码和刚才的差不多,唯一需要我们注意的是“listview嵌套listview,我们需要注意哪些问题”.

第一:listview和listview嵌套,子listview只显示一个多一点点,不能正常显示,解决办法:对listview重新设置起高度.(相信同学们对这个方法一点也不陌生.)

[java] view
plain
copy

  1. /***
  2. * 动态设置listview的高度
  3. *
  4. * @param listView
  5. */
  6. public void setListViewHeightBaseOnChildren(ListView listView) {
  7. ListAdapter listAdapter = listView.getAdapter();
  8. if (listAdapter == null)
  9. return;
  10. int totalHeight = 0;// 总高度
  11. for (int i = 0; i < listAdapter.getCount(); i++) {
  12. View listitem = listAdapter.getView(i, null, listView);
  13. listitem.measure(0, 0);
  14. totalHeight += listitem.getMeasuredHeight();
  15. }
  16. int totalDividerHeight = 0;
  17. totalDividerHeight = listView.getDividerHeight()
  18. * (listAdapter.getCount() - 1);
  19. ViewGroup.LayoutParams layoutParams = listView.getLayoutParams();
  20. layoutParams.height = totalHeight + totalDividerHeight;
  21. listView.setLayoutParams(layoutParams);
  22. }

第二个问题:listview 嵌套listview的时候,子listview会屏蔽掉父listview的焦点.使得父listview无法点击.

解决办法很简单:我们只需要在父listview的Adapter里面的配置文件最顶部的如LinearLayout加入一行:  android:descendantFocusability="blocksDescendants"就ok了.

效果图:

嗯,效果还可以吧,就介绍这么多了,如有问题或好的建议请吉留言.

ExpandableListView简单应用及listview模拟ExpandableListView的更多相关文章

  1. 53、listview、expandableListview如何选中时保持高亮?

    一.listView被选中后保持高亮 70down voteaccepted To hold the color of listview item when you press it, include ...

  2. jquery ajax json简单的分页,模拟数据,没有封装,只显示原理

    简单的分页,模拟数据,没有封装,显示原理,大家有兴趣可以自己封装,这里只是个原理过程,真正的分页也差不多是这个原理,只是请求数据不太一样,html部分: <!TOCTYPE HTML> & ...

  3. ListView模拟微信好友功能

    ListView模拟微信好友功能 效果图: 分析: 1.创建listView 2.创建数据 3.创建适配器 将数据放到呈现数据的容器里面. 将这个容器(带数据)连接适配器. 其实是直接在我们自己写的a ...

  4. 简单的横向ListView实现(version 3.0)

    版本号2仅仅是简单的实现了当手指按下的时候listView的Item向左移动一定的距离,并没有随着手指的左右移动而左右滚动.在这个版本号3.0中将会实现随着手指的移动而滚动的目标:当手指向左移动的时候 ...

  5. 可折叠的listview 之ExpandableListView基本使用

    先看效果 demo实现 其他的方法和ListView的方法一样,下面来看看具体demo的实现 首先布局文件很简单,就一个控件为: <?xml version="1.0" en ...

  6. Android ListView与ExpandableListView设置分割线divider

    listview设置分割线需要以下操作: lv.setDivider(getResources().getDrawable(R.drawable.diyline)); ExpandableListVi ...

  7. 简单的横向ListView实现(version 4.0)

    这个版本号的博客写起来颇费口舌.有些代码自己语言组织能力有限,感觉描写叙述起来非常费劲,前前后后改了五六遍稿子还是不尽人意 ,只是我还是坚持写出来自己当初的思路,假设看得不明确的地方我在文章最后仍然会 ...

  8. 简单几何(线段相交)+模拟 POJ 3449 Geometric Shapes

    题目传送门 题意:给了若干个图形,问每个图形与哪些图形相交 分析:题目说白了就是处理出每个图形的线段,然后判断是否相交.但是读入输出巨恶心,就是个模拟题加上线段相交的判断,我第一次WA不知道输出要按字 ...

  9. jQuery实现的简单文字提示效果模拟title(转)

    来源 http://www.cnblogs.com/puzi0315/archive/2012/10/17/2727693.html 模拟title实现效果,可以修改文字的样式,换行等. 文件下载: ...

随机推荐

  1. hdu 5476 (计算几何)

    题意:求三角形内∠MPB+∠APC=∠MPC+∠APB的轨迹长度- - 1.基于M的中垂线       2.三角形内的圆弧(比赛只有看自己能否猜中),ps.以下是别人家的证明 #include < ...

  2. [BZOJ]1014 火星人prefix(JSOI2008)

    一边听省队dalao讲课一边做题真TM刺激. BZOJ的discuss简直就是题面plus.大样例.SuperHINT.dalao题解的结合体. Description 火星人最近研究了一种操作:求一 ...

  3. Ubuntu 16.04 Vim安装及配置【转】

    转自:http://www.cnblogs.com/ace-wu/p/6273031.html 安装VIM 默认已经安装了VIM-tiny acewu@acewu-computer:~$ locate ...

  4. 异步 JavaScript 之 macrotask、microtask

    1.异步任务运行机制 先运行下面的一段代码: console.log('script start'); setTimeout(function() { console.log('setTimeout' ...

  5. 使用VMware Converter Standalone Client进行虚拟机 P2V提示 权限不足,无法连接\\ip\admin$的解决方法集锦

    使用VMware vCenter Converter Standalone Client进行虚拟机 P2V提示 权限不足,无法连接\\ip\admin$的解决方法集锦 步骤一 检查 远程桌面到&quo ...

  6. kindeditor配合requirejs使用时,ready失效

    KindEditor官方的文档在使用KindEditor时是这样的: KindEditor.ready(function(K)) { K.create('#editor_id'); } 使用了自己提供 ...

  7. 关于ES7中的async/await在客户端和服务端上的实践

    一.前言 在项目中经常遇到处理异步请求的情况,面对层层的嵌套,回调显示那么苍白无力: async / await是ES7的重要特性之一,也是目前社区里公认的优秀异步解决方案,既然这样就用上吧. 二.配 ...

  8. git reset揭秘

    一.命令 首先,让我们来解释几个定义.   HEAD(头)     指向当前branch最顶端的一个commit,该分支上一次commit后的节点   Index(索引)     The index, ...

  9. Docker部署Zabbix+Grafana监控

    Docker部署Zabbix+Grafana监控 环境 centos 7 ; Docker 17.12.0-ce ; docker-compose version 1.20.1 2018-4-1 当前 ...

  10. RobotFramework自动化测试框架-使用Python编写自定义的RobotFramework Lib

    使用Python构建Lib工程 可以用来开发Python Lib的IDE工具有很多,常见的有Pycharm,Eclipse with PyDev插件等,而且在RobotFramework官网中也已经提 ...