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

         

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

首先我们用到的控件是: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. [POI2000] 最长公共子串

    给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务 从文件中读入单词 计算最长公共子串的长度 输出结果到文件 输入 文件的第一行是整数 n,1<=n<=5,表示单词的数量.接 ...

  2. hdu 1043(经典搜索)

    题意: 给你一个初始的图,然后每次输入一个图,要求移动x最小的步数达到和初始图一样,输出路径 1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 5 6 7 8 5 6 7 8 5 6 7 ...

  3. bzoj 1046: [HAOI2007]上升序列

    Description 对于一个给定的S={a1,a2,a3,…,an},若有P={ax1,ax2,ax3,…,axm},满足(x1 < x2 < … < xm)且( ax1 < ...

  4. Timestamp转Calendar

    Timestamp scheduleTime = r.getTimestamp("time_recv"); Calendar calendarScheduleTime = Cale ...

  5. WPF ViewModel与多个View绑定后如何解决的问题

    当重复创建View并绑定同一个ViewModel后,ViewModel中的字段更新,在新的View中的没有反应或者在View中找不到相应的视觉树(如ListBox的ListBoxItem) 初始的解决 ...

  6. log4j日志的基本使用方法(1)——概述、配置文件

    一.概述 Log4j由三个重要的组件构成:日志信息的优先级,日志信息的输出目的地,日志信息的输出格式.日志信息的优先级从高到低有ERROR.WARN.INFO.DEBUG,分别用来指定这条日志信息的重 ...

  7. rhel7 配置普通用户使用sudo

    rhel服务器版本安装之后,默认创建的用户不能使用sudo.使用sudo,会提示 user1 is not in the sudoers file. This incident will be rep ...

  8. PyCharm 2018.1破解过程

    一.下载 首先从官网下载 官网,如果开了酸酸乳的话无法下载,官网会自动断开连接.所以下载时请关闭酸酸乳 二.安装 选择安装路径 选择64位,创建关联.py文件 安装完后运行Pycharm 选择不导入开 ...

  9. python笔记八(切片)

    一.切片 首先我们要记得在Python中可以用于切片的对象有 列表.元组.字符串. 切片操作就是直接从列表.元组或字符串中,选择出我们想要的内容,这些操作非常简洁实用. >>> L ...

  10. ng-book札记——Angular工作方式

    Angular应用由组件(Component)构成.它与AngularJS中的指令相似(directive). 应用 一个Angular应用本质上是一个组件树.在组件树的顶层,最上级的组件即是应用本身 ...