/********************************LIstView模拟ExpandableListView**************************************************************/
下面我们看一个案例:

其实就是:点击listview的一个item,展开其孩子,点击另一个item,打开其孩子,关闭之前那个孩子.
这个眨一看是ExpandableListView这个东东,可是本人比较笨戳,整了好久没有弄出来,最终放弃,google下,发现有人用listview来模拟实现,也就跟着做了下.
布局文件:(后面多个隐藏text.)
- <?xml version="1.0"encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@color/white"
- android:gravity="center_vertical"
- android:orientation="vertical">
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/selector_group"
- android:gravity="center_vertical"
- android:orientation="horizontal"
- android:padding="5dp">
- <TextView
- android:id="@+id/group"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:textColor="@color/black"/>
- <ImageView
- android:id="@+id/image"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_centerVertical="true"
- android:src=http://blog.youkuaiyun.com/jj120522/article/details/"@drawable/collapse" />
- </RelativeLayout>
- <TextView
- android:id="@+id/hint_item"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:gravity="center_vertical"
- android:padding="10dp"
- android:textColor="@color/black"
- android:visibility="gone"/>
- </LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:gravity="center_vertical"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/selector_group"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="5dp" >
<TextView
android:id="@+id/group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textColor="@color/black" />
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src=http://blog.youkuaiyun.com/jj120522/article/details/"@drawable/collapse" />
</RelativeLayout>
<TextView
android:id="@+id/hint_item"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:padding="10dp"
android:textColor="@color/black"
android:visibility="gone" />
</LinearLayout>
MyAdpter.java
- /***
- * 数据源
- *
- * @author zhangjia
- *
- */
- classMyAdpter extendsBaseAdapter {
- privateContext context;
- privateLayoutInflater inflater;
- privateintchange_index = -1;// 改变项
- publicMyAdpter(Context context) {
- super();
- this.context = context;
- inflater = (LayoutInflater) context
- .getSystemService(context.LAYOUT_INFLATER_SERVICE);
- }
- @Override
- publicintgetCount() {
- returngroupList.size();
- }
- @Override
- publicObject getItem(intposition) {
- returngroupList.get(position);
- }
- @Override
- publiclonggetItemId(intposition) {
- returnposition;
- }
- @Override
- publicView getView(intposition, View convertView, ViewGroup parent) {
- GroupHolder groupHolder = null;
- if(convertView == null) {
- groupHolder = newGroupHolder();
- convertView = inflater.inflate(R.layout.group, null);
- groupHolder.textView = (TextView) convertView
- .findViewById(R.id.group);
- groupHolder.imageView = (ImageView) convertView
- .findViewById(R.id.image);
- groupHolder.hint_item = (TextView) convertView
- .findViewById(R.id.hint_item);
- convertView.setTag(groupHolder);
- } else{
- groupHolder = (GroupHolder) convertView.getTag();
- }
- groupHolder.textView.setText(groupList.get(position));
- groupHolder.hint_item.setText(childList.get(position));
- if(change_index == position)
- groupHolder.hint_item.setVisibility(View.VISIBLE);
- else
- groupHolder.hint_item.setVisibility(View.GONE);
- returnconvertView;
- }
- /***
- * 这个方法用于更改子item的状态
- */
- publicvoidchangeImageVisable(View view, intposition) {
- // 隐藏提示
- if(change_index == position) {
- GroupHolder groupHolder = (GroupHolder) view.getTag();
- if(groupHolder.hint_item.getVisibility() == View.VISIBLE)
- groupHolder.hint_item.setVisibility(View.GONE);
- else
- groupHolder.hint_item.setVisibility(View.VISIBLE);
- } else{
- change_index = position;
- notifyDataSetChanged();// restart getview
- }
- }
- }
/***
* 数据源
*
* @author zhangjia
*
*/
class MyAdpter extends BaseAdapter {
private Context context;
private LayoutInflater inflater;
private int change_index = -1;// 改变项
public MyAdpter(Context context) {
super();
this.context = context;
inflater = (LayoutInflater) context
.getSystemService(context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return groupList.size();
}
@Override
public Object getItem(int position) {
return groupList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
GroupHolder groupHolder = null;
if (convertView == null) {
groupHolder = new GroupHolder();
convertView = inflater.inflate(R.layout.group, null);
groupHolder.textView = (TextView) convertView
.findViewById(R.id.group);
groupHolder.imageView = (ImageView) convertView
.findViewById(R.id.image);
groupHolder.hint_item = (TextView) convertView
.findViewById(R.id.hint_item);
convertView.setTag(groupHolder);
} else {
groupHolder = (GroupHolder) convertView.getTag();
}
groupHolder.textView.setText(groupList.get(position));
groupHolder.hint_item.setText(childList.get(position));
if (change_index == position)
groupHolder.hint_item.setVisibility(View.VISIBLE);
else
groupHolder.hint_item.setVisibility(View.GONE);
return convertView;
}
/***
* 这个方法用于更改子item的状态
*/
public void changeImageVisable(View view, int position) {
// 隐藏提示
if (change_index == position) {
GroupHolder groupHolder = (GroupHolder) view.getTag();
if (groupHolder.hint_item.getVisibility() == View.VISIBLE)
groupHolder.hint_item.setVisibility(View.GONE);
else
groupHolder.hint_item.setVisibility(View.VISIBLE);
} else {
change_index = position;
notifyDataSetChanged();// restart getview
}
}
}
这个数据源很简单,只是多了个用于控制孩子隐藏与显示的方法changeImageVisable.代码很简单,相信不用过多解释.
效果:


上面模拟显示的孩子是一个textview(缺点:隐藏textview显示时候点击会影响到其父控件,大家尝试一下,不过肯定有解决办法的.),
下面我来介绍下,如果孩子是listview应该怎么办.
首先配置文件:
- <?xml version="1.0"encoding="utf-8"?>
- <!-- android:descendantFocusability="blocksDescendants"这个属性就可以让父listview获取焦点 -->
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@color/white"
- android:descendantFocusability="blocksDescendants"
- android:gravity="center_vertical"
- android:orientation="vertical">
- <RelativeLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/selector_group"
- android:gravity="center_vertical"
- android:orientation="horizontal"
- android:padding="5dp">
- <TextView
- android:id="@+id/group"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerVertical="true"
- android:text="精品推荐"
- android:textColor="@color/black"/>
- <ImageView
- android:id="@+id/image"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_centerVertical="true"
- android:src=http://blog.youkuaiyun.com/jj120522/article/details/"@drawable/collapse" />
- </RelativeLayout>
- <ListView
- android:id="@+id/hint_item"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:gravity="center_vertical"
- android:textColor="@color/black"/>
- </LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<!-- android:descendantFocusability="blocksDescendants"这个属性就可以让父listview获取焦点 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:descendantFocusability="blocksDescendants"
android:gravity="center_vertical"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/selector_group"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="5dp" >
<TextView
android:id="@+id/group"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="精品推荐"
android:textColor="@color/black" />
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src=http://blog.youkuaiyun.com/jj120522/article/details/"@drawable/collapse" />
</RelativeLayout>
<ListView
android:id="@+id/hint_item"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:textColor="@color/black" />
</LinearLayout>
- /***
- * InitData
- */
- voidInitData() {
- groupList = newArrayList<String>();
- groupList.add("Ios");
- groupList.add("Android");
- groupList.add("Window");
- childList = newArrayList<ArrayList<String>>();
- for(inti = 0; i < groupList.size(); i++) {
- ArrayList<String> childTemp;
- if(i == 0) {
- childTemp = newArrayList<String>();
- childTemp.add("iphone 4");
- childTemp.add("iphone 5");
- } elseif(i == 1) {
- childTemp = newArrayList<String>();
- childTemp.add("Anycall");
- childTemp.add("HTC");
- childTemp.add("Motorola");
- } else{
- childTemp = newArrayList<String>();
- childTemp.add("Lumia 800C ");
- }
- childList.add(childTemp);
- }
- }
/***
* InitData
*/
void InitData() {
groupList = new ArrayList<String>();
groupList.add("Ios");
groupList.add("Android");
groupList.add("Window");
childList = new ArrayList<ArrayList<String>>();
for (int i = 0; i < groupList.size(); i++) {
ArrayList<String> childTemp;
if (i == 0) {
childTemp = new ArrayList<String>();
childTemp.add("iphone 4");
childTemp.add("iphone 5");
} else if (i == 1) {
childTemp = new ArrayList<String>();
childTemp.add("Anycall");
childTemp.add("HTC");
childTemp.add("Motorola");
} else {
childTemp = new ArrayList<String>();
childTemp.add("Lumia 800C ");
}
childList.add(childTemp);
}
}
- /***
- * 父数据源
- *
- * @author zhangjia
- *
- */
- classMyAdpter extendsBaseAdapter {
- privateContext context;
- privateLayoutInflater inflater;
- privateintchange_index = -1;// 改变项
- publicMyAdpter(Context context) {
- super();
- this.context = context;
- inflater = (LayoutInflater) context
- .getSystemService(context.LAYOUT_INFLATER_SERVICE);
- }
- @Override
- publicintgetCount() {
- returngroupList.size();
- }
- @Override
- publicObject getItem(intposition) {
- returngroupList.get(position);
- }
- @Override
- publiclonggetItemId(intposition) {
- returnposition;
- }
- @Override
- publicView getView(finalintposition, View convertView,
- ViewGroup parent) {
- GroupHolder groupHolder = null;
- if(convertView == null) {
- groupHolder = newGroupHolder();
- convertView = inflater.inflate(R.layout.group_item, null);
- groupHolder.textView = (TextView) convertView
- .findViewById(R.id.group);
- groupHolder.imageView = (ImageView) convertView
- .findViewById(R.id.image);
- groupHolder.hint_item = (ListView) convertView
- .findViewById(R.id.hint_item);
- convertView.setTag(groupHolder);
- } else{
- groupHolder = (GroupHolder) convertView.getTag();
- }
- groupHolder.textView.setText(groupList.get(position));
- groupHolder.hint_item.setAdapter(getListView(childList
- .get(position)));
- groupHolder.hint_item
- .setOnItemClickListener(newOnItemClickListener() {
- @Override
- publicvoidonItemClick(AdapterView<?> parent,
- View view, intposition_id, longid) {
- Toast.makeText(context,
- childList.get(position).get(position_id), 1)
- .show();
- }
- });
- // 动态设置listview 的高度
- setListViewHeightBaseOnChildren(groupHolder.hint_item);
- if(change_index == position) {
- groupHolder.hint_item.setVisibility(View.VISIBLE);
- groupHolder.imageView.setImageResource(R.drawable.expanded);
- }
- else{
- groupHolder.hint_item.setVisibility(View.GONE);
- groupHolder.imageView.setImageResource(R.drawable.collapse);
- }
- returnconvertView;
- }
- /***
- * 这个方法用于更改子item的状态
- */
- publicvoidchangeImageVisable(View view, intposition) {
- // 隐藏提示
- if(change_index == position) {
- GroupHolder groupHolder = (GroupHolder) view.getTag();
- if(groupHolder.hint_item.getVisibility() == View.VISIBLE)
- groupHolder.hint_item.setVisibility(View.GONE);
- else
- groupHolder.hint_item.setVisibility(View.VISIBLE);
- } else{
- change_index = position;
- notifyDataSetChanged();// restart getview
- }
- }
- }
/***
* 父数据源
*
* @author zhangjia
*
*/
class MyAdpter extends BaseAdapter {
private Context context;
private LayoutInflater inflater;
private int change_index = -1;// 改变项
public MyAdpter(Context context) {
super();
this.context = context;
inflater = (LayoutInflater) context
.getSystemService(context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return groupList.size();
}
@Override
public Object getItem(int position) {
return groupList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView,
ViewGroup parent) {
GroupHolder groupHolder = null;
if (convertView == null) {
groupHolder = new GroupHolder();
convertView = inflater.inflate(R.layout.group_item, null);
groupHolder.textView = (TextView) convertView
.findViewById(R.id.group);
groupHolder.imageView = (ImageView) convertView
.findViewById(R.id.image);
groupHolder.hint_item = (ListView) convertView
.findViewById(R.id.hint_item);
convertView.setTag(groupHolder);
} else {
groupHolder = (GroupHolder) convertView.getTag();
}
groupHolder.textView.setText(groupList.get(position));
groupHolder.hint_item.setAdapter(getListView(childList
.get(position)));
groupHolder.hint_item
.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent,
View view, int position_id, long id) {
Toast.makeText(context,
childList.get(position).get(position_id), 1)
.show();
}
});
// 动态设置listview 的高度
setListViewHeightBaseOnChildren(groupHolder.hint_item);
if (change_index == position) {
groupHolder.hint_item.setVisibility(View.VISIBLE);
groupHolder.imageView.setImageResource(R.drawable.expanded);
}
else {
groupHolder.hint_item.setVisibility(View.GONE);
groupHolder.imageView.setImageResource(R.drawable.collapse);
}
return convertView;
}
/***
* 这个方法用于更改子item的状态
*/
public void changeImageVisable(View view, int position) {
// 隐藏提示
if (change_index == position) {
GroupHolder groupHolder = (GroupHolder) view.getTag();
if (groupHolder.hint_item.getVisibility() == View.VISIBLE)
groupHolder.hint_item.setVisibility(View.GONE);
else
groupHolder.hint_item.setVisibility(View.VISIBLE);
} else {
change_index = position;
notifyDataSetChanged();// restart getview
}
}
}
上面代码和刚才的差不多,唯一需要我们注意的是“
listview嵌套listview,我们需要注意哪些问题”.
第一:listview和listview嵌套,子listview只显示一个多一点点,不能正常显示,解决办法:对listview重新设置起高度.(相信同学们对这个方法一点也不陌生.)
- /***
- * 动态设置listview的高度
- *
- * @param listView
- */
- publicvoidsetListViewHeightBaseOnChildren(ListView listView) {
- ListAdapter listAdapter = listView.getAdapter();
- if(listAdapter == null)
- return;
- inttotalHeight = 0;// 总高度
- for(inti = 0; i < listAdapter.getCount(); i++) {
- View listitem = listAdapter.getView(i, null, listView);
- listitem.measure(0, 0);
- totalHeight += listitem.getMeasuredHeight();
- }
- inttotalDividerHeight = 0;
- totalDividerHeight = listView.getDividerHeight()
- * (listAdapter.getCount() - 1);
- ViewGroup.LayoutParams layoutParams = listView.getLayoutParams();
- layoutParams.height = totalHeight + totalDividerHeight;
- listView.setLayoutParams(layoutParams);
- }
/***
* 动态设置listview的高度
*
* @param listView
*/
public void setListViewHeightBaseOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
return;
int totalHeight = 0;// 总高度
for (int i = 0; i < listAdapter.getCount(); i++) {
View listitem = listAdapter.getView(i, null, listView);
listitem.measure(0, 0);
totalHeight += listitem.getMeasuredHeight();
}
int totalDividerHeight = 0;
totalDividerHeight = listView.getDividerHeight()
* (listAdapter.getCount() - 1);
ViewGroup.LayoutParams layoutParams = listView.getLayoutParams();
layoutParams.height = totalHeight + totalDividerHeight;
listView.setLayoutParams(layoutParams);
}
第二个问题:
listview 嵌套listview的时候,子listview会屏蔽掉父listview的焦点.使得父listview无法点击.
解决办法很简单:我们只需要在父listview的Adapter里面的配置文件最顶部的如LinearLayout加入一行: android:descendantFocusability="blocksDescendants"就ok了.
效果图: