expandableListView 自定义样式以及scrollerView嵌套
2016-01-15 17:43
477 查看
最近写项目需要用到ExpandableListView,由于第一次使用,被它各种虐。网上也查看很多资料,但都没有实质的对它做个总结。本人不才,把自己项目中遇到的问题小记一下,分享给初学者。(部分是网上copy的,敬请谅解)
ExpandableListView组件是android中一个比较常用的组件,当点击一个父item的时候可以将他的子item显示出来,像手机QQ中的好友列表就是实现的类型效果。
1、Expandablelistview的基本使用:
第一步:在main.xml中定义ExpandableListView(由于项目的需求要scrollerView嵌套ExpandableListView所以这里引用的事自定义的)
<com.demo.widget.ScrollDisabledExpandableListView
android:id="@+id/yuncomputer_screen_id_expandablelist"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/yuncomputer_screen_id_tips"
android:dividerHeight="1dp"
android:childDivider="#e3e3e3"
android:divider="#e3e3e3"
android:listSelector="@color/no_color" />
注:如果要定义分割线的颜色,divider属性要直接写颜色值,要不然会不显示
第二步:定义group.xml
<TextView android:id="@+id/group_id_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textColor="@color/black"
android:textSize="17sp"
android:paddingLeft="10dp"
/>
注:由于我要自定义箭头而且要更改箭头位置所以这里多了个imageView。
第三步:定义chilid.xml
<TextView android:id="@+id/child_id_pkg_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/black"
android:textSize="17sp"
/>
第四步:重头戏,适配BaseExpandableListAdapter
public class MyAdapter extends BaseExpandableListAdapter {
List<String> groups;
Map<String, List<String>> packages;
Context context;
public YunPackageAdapter(Context context,List<String> groups,Map<String, List<String>> packages){
super();
this.context = context;
this.groups = groups;
this.packages = packages;
}
/**
* 获取父item的个数
*/
@Override
public int getGroupCount() {
// TODO Auto-generated method stub
return groups.size();
}
/**
* 获取当前父item下的子item的个数
*/
@Override
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
String strKey = groups.get(groupPosition);
return packages.get(strKey).size();
}
/**
* 获取当前父item的数据
*/
@Override
public Object getGroup(int groupPosition) {
// TODO Auto-generated method stub
return groups.get(groupPosition);
}
/**
* 得到子item需要关联的数据
*/
@Override
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
String strKey = groups.get(groupPosition);
return packages.get(strKey).get(childPosition);
}
/**
* 获取父item的ID
*/
@Override
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return groupPosition;
}
/**
* 获取子item的ID
*/
@Override
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return childPosition;
}
@Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return true;
}
/**
* 设置父item组件(这里是自定义的箭头)
*/
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
convertView = LayoutInflater.from(context).inflate(R.layout.group, null);
ImageView imgIndicator = (ImageView) convertView.findViewById(R.id.group_id_indicator);
TextView tvName = (TextView) convertView.findViewById(R.id.group_id_name);
tvName.setText(groups.get(groupPosition));
//key值必须为资源ID
convertView.setTag(R.layout.item_yuncomputer_group, groupPosition);
convertView.setTag(R.layout.item_yuncomputer_child,-1);//设置-1表示长按时点击的是父项。
return convertView;
}
/**
* 设置item的组件
*/
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
convertView = LayoutInflater.from(context).inflate(R.layout.child, null);
TextView tvPackageName = (TextView) convertView.findViewById(R.id.child_id_name);
convertView.setTag(R.layout.item_yuncomputer_child,childPosition);
convertView.setTag(R.layout.item_yuncomputer_group, groupPosition);
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return true;
}
}
2、自定义groupIndicator
a、直接给groupIndicator自定义图片,为了图片不变形,要.9图片。缺点:只能通过.9图片大致调整箭头的位置,indicatorLeft属性对于某些终端不起作用,具体为啥我也不清楚。
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/list_item_expand" android:state_expanded="true"/>
<item android:drawable="@drawable/list_item_collapse"></item>
</selector>
===================================================
<ExpandableListView
…
android:groupIndicator="@drawable/list_expand"
…
/>
b、网上零零碎碎很多方法,我认为的最简单有效的是:
在group中自定义箭头,这样样式、位置就能精准配置了:首先
在group的xml中加入:
<ImageView android:id="@+id/group_id_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:scaleType="fitCenter"
android:src="@drawable/yuncomputer_close"
/>
再者:android:groupIndicator="@null"必须设置为null要不然会出现重叠的箭头而且自定义的无效;
然后在adapter中的getGroupView方法中加入:
if(isExpanded){
imgIndicator.setImageResource(R.drawable.open);
}else{
imgIndicator.setImageResource(R.drawable.close);
}
大功告成,啦啦啦啦......
3、对ExpandableListView的item点击事件是OnChildClickListener: onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) 同时控制groupPosition和childPosition才能精确控制点击的是哪一个item。
4、对ExpandableListView的item的长按事件:(此处为转载:转载地址:http://blog.csdn.net/t5721654/article/details/6857357)
关于ExpandableListView长按事件处理,网上很多都是使用将上下文菜单注册到ExpandableListView上实现长按事件。
/**
* 长按邮箱快捷选项
* @author King
*/
private class QuickWayListener implements OnItemLongClickListener{
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View view,
int pos, long id) {
int groupPos = (Integer)view.getTag(R.id.xxx01); //参数值是在setTag时使用的对应资源id号
int childPos = (Integer)view.getTag(R.id.xxx02);
if(childPos == -1){//长按的是父项
//根据groupPos判断你长按的是哪个父项,做相应处理(弹框等)
} else {
//根据groupPos及childPos判断你长按的是哪个父项下的哪个子项,然后做相应处理。
}
return false;
}
}
这样做弊端显而易见,不够灵活,不能分别对父项、子项、父项之间、子项之间弹出内容做区分。
下面来说我的解决方法,方法有点投机取巧。首先说明一点,使用我这种方法必须使用自定义的BaseExpandableListAdapter,至于为什么,具体后面讲到。
ExpandableListView本身有继承自AdapterView的setOnItemLongClickListener(AdapterView.OnItemLongClickListener listener)方法。
实现监听器:
/**
* 长按邮箱快捷选项
* @author King
*/
private class QuickWayListener implements OnItemLongClickListener{
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View view,
int pos, long id) {
//pos不可用说明见下文
return false;
}
}
如果这个方法是用在ListView长按事件中刚刚好,但在ExpandableListView中,第三个参数pos不能区分开点击的是父项还是子项,以及哪个父项或子项。
在ExpandableListView响应的onItemLongCkick方法中,pos参数值为:从上到下,父项+展现的子项到点击位置的数目(注意:是展现的,隐藏的子项不包括,从0开始)。
例如:
父项1(隐藏3个子项)
父项2
|—子项2-0
|—子项2-1
|—子项2-2
长按子项2-1时,pos值为3。显然根据pos值是无法确定点击的是哪个子项或父项的。
因此依赖pos是很难处理点击位置的。
如果可以直接在onItemLongClick方法中获取groupPos,及childPos该多好呢?
于是看到了onItemLongClick方法第二个参数:view。这里的view是你按中的位置对应的view。view有个方法getTag(int key)。如果在创建此view的时候就把groupPos,childPos通过setTag(int key, Object value)设置进去,在响应onItemLongClick不就可以直接拿出来用了么。
现在就要讲到必须使用自定义的BaseExpandableListAdapter的理由了。
要把groupPos,childPos通过setTag的方式绑定到view中,就必须操作该view的创建过程。要控制这个过程就必须要在自定义BaseExpandableListAdapter中重写getGroupView及getChildView方法进行操作。如下:
public class AccountListAdapter extends BaseExpandableListAdapter {
...省略其他方法
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
//我这里仅通过自己写的mkChildView()方法创建TextView来显示文字,更复杂的可以通过LayoutInflater来填充一个view
TextView childTv = mkChildView();
// 标记位置
// 必须使用资源Id当key(不是资源id会出现运行时异常),android本意应该是想用tag来保存资源id对应组件。
// 将groupPosition,childPosition通过setTag保存,在onItemLongClick方法中就可以通过view参数直接拿到了!
childTv.setTag(R.id.xxx01, groupPosition);
childTv.setTag(R.id.xxx02, childPosition);
return childTv;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
TextView groupTv = mkGroupView();
// 设置同getChildView一样
groupTv.setTag(R.id.xxx01, groupPosition);
groupTv.setTag(R.id.xxx02, -1); //设置-1表示长按时点击的是父项,到时好判断。
groupTv.setText(groups[groupPosition]);
return groupTv;
}
}
完成了这一步,我们只需要在ExpandableListView响应的onItemLongClick方法时通过view.getTag(R.id.xxx01),view.getTag(R.id.xxx02)即可拿到groupPos,childPos.
/**
* 长按邮箱快捷选项
* @author King
*/
private class QuickWayListener implements OnItemLongClickListener{
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View view,
int pos, long id) {
int groupPos = (Integer)view.getTag(R.id.xxx01); //参数值是在setTag时使用的对应资源id号
int childPos = (Integer)view.getTag(R.id.xxx02);
if(childPos == -1){//长按的是父项
//根据groupPos判断你长按的是哪个父项,做相应处理(弹框等)
} else {
//根据groupPos及childPos判断你长按的是哪个父项下的哪个子项,然后做相应处理。
}
return false;
}
}
到这就写完了,貌似比较啰嗦。重写BaseExpandableListAdapter写的比较简洁,没看明白的朋友可以先到网上查下怎么自定义BaseExpandableListAdapter,和自定义BaseAdapter其实是一样的。
这个部分为转载,亲测实在是好用得不得了(偷笑)。
5、scrollerView嵌套ExpandableListView:
a、重写ExpandableListView
public class CustomExpandableListView extends ExpandableListView {
public CustomExpandableListView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
b、动态计算expandablelistview的高度,xxx_group.xml和xxx_child.xml的最外层要用linearlayout,反正relativelayout不行,不知道为什么
private void setListViewHeight(ExpandableListView listView) {
ListAdapter listAdapter = listView.getAdapter();
int totalHeight = 0;
int count = listAdapter.getCount();
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
c、较为复杂
public class ViewGroupForListView extends LinearLayout implements View.OnClickListener {
private ListAdapter mAdapter = null;
private OnItemClickListener mListener = null;
public ViewGroupForListView(Context context) {
super(context);
}
public ViewGroupForListView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
this.setOrientation(VERTICAL);
}
/**
* 绑定数据
*/
protected void bindData() {
int count = mAdapter.getCount();
for(int i = 0; i < count; i++) {
View v = mAdapter.getView(i, null, null);
v.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
v.setOnClickListener(this);
v.setId(i);
addView(v, i);
}
}
/**
* 设置adapter
* @param adapter
*/
public void setAdapter(ListAdapter adapter) {
mAdapter = adapter;
if(this.getChildCount() != 0) {
removeAllViews();
}
bindData();
}
/**
* 获取adapter
* @return
*/
public ListAdapter getAdapter() {
return mAdapter;
}
/**
* 绑定监听
* @param listener
*/
public void setOnItemClickListener(OnItemClickListener listener) {
this.mListener = listener;
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(mListener != null) {
mListener.onItemClick(v.getId(), mAdapter);
}
}
/**
* 监听接口
* @author Visual
*
*/
public interface OnItemClickListener {
public void onItemClick(int position, ListAdapter adapter);
}
ExpandableListView组件是android中一个比较常用的组件,当点击一个父item的时候可以将他的子item显示出来,像手机QQ中的好友列表就是实现的类型效果。
1、Expandablelistview的基本使用:
第一步:在main.xml中定义ExpandableListView(由于项目的需求要scrollerView嵌套ExpandableListView所以这里引用的事自定义的)
<com.demo.widget.ScrollDisabledExpandableListView
android:id="@+id/yuncomputer_screen_id_expandablelist"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/yuncomputer_screen_id_tips"
android:dividerHeight="1dp"
android:childDivider="#e3e3e3"
android:divider="#e3e3e3"
android:listSelector="@color/no_color" />
注:如果要定义分割线的颜色,divider属性要直接写颜色值,要不然会不显示
第二步:定义group.xml
<TextView android:id="@+id/group_id_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textColor="@color/black"
android:textSize="17sp"
android:paddingLeft="10dp"
/>
注:由于我要自定义箭头而且要更改箭头位置所以这里多了个imageView。
第三步:定义chilid.xml
<TextView android:id="@+id/child_id_pkg_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/black"
android:textSize="17sp"
/>
第四步:重头戏,适配BaseExpandableListAdapter
public class MyAdapter extends BaseExpandableListAdapter {
List<String> groups;
Map<String, List<String>> packages;
Context context;
public YunPackageAdapter(Context context,List<String> groups,Map<String, List<String>> packages){
super();
this.context = context;
this.groups = groups;
this.packages = packages;
}
/**
* 获取父item的个数
*/
@Override
public int getGroupCount() {
// TODO Auto-generated method stub
return groups.size();
}
/**
* 获取当前父item下的子item的个数
*/
@Override
public int getChildrenCount(int groupPosition) {
// TODO Auto-generated method stub
String strKey = groups.get(groupPosition);
return packages.get(strKey).size();
}
/**
* 获取当前父item的数据
*/
@Override
public Object getGroup(int groupPosition) {
// TODO Auto-generated method stub
return groups.get(groupPosition);
}
/**
* 得到子item需要关联的数据
*/
@Override
public Object getChild(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
String strKey = groups.get(groupPosition);
return packages.get(strKey).get(childPosition);
}
/**
* 获取父item的ID
*/
@Override
public long getGroupId(int groupPosition) {
// TODO Auto-generated method stub
return groupPosition;
}
/**
* 获取子item的ID
*/
@Override
public long getChildId(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return childPosition;
}
@Override
public boolean hasStableIds() {
// TODO Auto-generated method stub
return true;
}
/**
* 设置父item组件(这里是自定义的箭头)
*/
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
convertView = LayoutInflater.from(context).inflate(R.layout.group, null);
ImageView imgIndicator = (ImageView) convertView.findViewById(R.id.group_id_indicator);
TextView tvName = (TextView) convertView.findViewById(R.id.group_id_name);
tvName.setText(groups.get(groupPosition));
//key值必须为资源ID
convertView.setTag(R.layout.item_yuncomputer_group, groupPosition);
convertView.setTag(R.layout.item_yuncomputer_child,-1);//设置-1表示长按时点击的是父项。
return convertView;
}
/**
* 设置item的组件
*/
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
convertView = LayoutInflater.from(context).inflate(R.layout.child, null);
TextView tvPackageName = (TextView) convertView.findViewById(R.id.child_id_name);
convertView.setTag(R.layout.item_yuncomputer_child,childPosition);
convertView.setTag(R.layout.item_yuncomputer_group, groupPosition);
return convertView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
// TODO Auto-generated method stub
return true;
}
}
2、自定义groupIndicator
a、直接给groupIndicator自定义图片,为了图片不变形,要.9图片。缺点:只能通过.9图片大致调整箭头的位置,indicatorLeft属性对于某些终端不起作用,具体为啥我也不清楚。
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/list_item_expand" android:state_expanded="true"/>
<item android:drawable="@drawable/list_item_collapse"></item>
</selector>
===================================================
<ExpandableListView
…
android:groupIndicator="@drawable/list_expand"
…
/>
b、网上零零碎碎很多方法,我认为的最简单有效的是:
在group中自定义箭头,这样样式、位置就能精准配置了:首先
在group的xml中加入:
<ImageView android:id="@+id/group_id_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:scaleType="fitCenter"
android:src="@drawable/yuncomputer_close"
/>
再者:android:groupIndicator="@null"必须设置为null要不然会出现重叠的箭头而且自定义的无效;
然后在adapter中的getGroupView方法中加入:
if(isExpanded){
imgIndicator.setImageResource(R.drawable.open);
}else{
imgIndicator.setImageResource(R.drawable.close);
}
大功告成,啦啦啦啦......
3、对ExpandableListView的item点击事件是OnChildClickListener: onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) 同时控制groupPosition和childPosition才能精确控制点击的是哪一个item。
4、对ExpandableListView的item的长按事件:(此处为转载:转载地址:http://blog.csdn.net/t5721654/article/details/6857357)
关于ExpandableListView长按事件处理,网上很多都是使用将上下文菜单注册到ExpandableListView上实现长按事件。
/**
* 长按邮箱快捷选项
* @author King
*/
private class QuickWayListener implements OnItemLongClickListener{
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View view,
int pos, long id) {
int groupPos = (Integer)view.getTag(R.id.xxx01); //参数值是在setTag时使用的对应资源id号
int childPos = (Integer)view.getTag(R.id.xxx02);
if(childPos == -1){//长按的是父项
//根据groupPos判断你长按的是哪个父项,做相应处理(弹框等)
} else {
//根据groupPos及childPos判断你长按的是哪个父项下的哪个子项,然后做相应处理。
}
return false;
}
}
这样做弊端显而易见,不够灵活,不能分别对父项、子项、父项之间、子项之间弹出内容做区分。
下面来说我的解决方法,方法有点投机取巧。首先说明一点,使用我这种方法必须使用自定义的BaseExpandableListAdapter,至于为什么,具体后面讲到。
ExpandableListView本身有继承自AdapterView的setOnItemLongClickListener(AdapterView.OnItemLongClickListener listener)方法。
实现监听器:
/**
* 长按邮箱快捷选项
* @author King
*/
private class QuickWayListener implements OnItemLongClickListener{
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View view,
int pos, long id) {
//pos不可用说明见下文
return false;
}
}
如果这个方法是用在ListView长按事件中刚刚好,但在ExpandableListView中,第三个参数pos不能区分开点击的是父项还是子项,以及哪个父项或子项。
在ExpandableListView响应的onItemLongCkick方法中,pos参数值为:从上到下,父项+展现的子项到点击位置的数目(注意:是展现的,隐藏的子项不包括,从0开始)。
例如:
父项1(隐藏3个子项)
父项2
|—子项2-0
|—子项2-1
|—子项2-2
长按子项2-1时,pos值为3。显然根据pos值是无法确定点击的是哪个子项或父项的。
因此依赖pos是很难处理点击位置的。
如果可以直接在onItemLongClick方法中获取groupPos,及childPos该多好呢?
于是看到了onItemLongClick方法第二个参数:view。这里的view是你按中的位置对应的view。view有个方法getTag(int key)。如果在创建此view的时候就把groupPos,childPos通过setTag(int key, Object value)设置进去,在响应onItemLongClick不就可以直接拿出来用了么。
现在就要讲到必须使用自定义的BaseExpandableListAdapter的理由了。
要把groupPos,childPos通过setTag的方式绑定到view中,就必须操作该view的创建过程。要控制这个过程就必须要在自定义BaseExpandableListAdapter中重写getGroupView及getChildView方法进行操作。如下:
public class AccountListAdapter extends BaseExpandableListAdapter {
...省略其他方法
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
//我这里仅通过自己写的mkChildView()方法创建TextView来显示文字,更复杂的可以通过LayoutInflater来填充一个view
TextView childTv = mkChildView();
// 标记位置
// 必须使用资源Id当key(不是资源id会出现运行时异常),android本意应该是想用tag来保存资源id对应组件。
// 将groupPosition,childPosition通过setTag保存,在onItemLongClick方法中就可以通过view参数直接拿到了!
childTv.setTag(R.id.xxx01, groupPosition);
childTv.setTag(R.id.xxx02, childPosition);
return childTv;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
TextView groupTv = mkGroupView();
// 设置同getChildView一样
groupTv.setTag(R.id.xxx01, groupPosition);
groupTv.setTag(R.id.xxx02, -1); //设置-1表示长按时点击的是父项,到时好判断。
groupTv.setText(groups[groupPosition]);
return groupTv;
}
}
完成了这一步,我们只需要在ExpandableListView响应的onItemLongClick方法时通过view.getTag(R.id.xxx01),view.getTag(R.id.xxx02)即可拿到groupPos,childPos.
/**
* 长按邮箱快捷选项
* @author King
*/
private class QuickWayListener implements OnItemLongClickListener{
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View view,
int pos, long id) {
int groupPos = (Integer)view.getTag(R.id.xxx01); //参数值是在setTag时使用的对应资源id号
int childPos = (Integer)view.getTag(R.id.xxx02);
if(childPos == -1){//长按的是父项
//根据groupPos判断你长按的是哪个父项,做相应处理(弹框等)
} else {
//根据groupPos及childPos判断你长按的是哪个父项下的哪个子项,然后做相应处理。
}
return false;
}
}
到这就写完了,貌似比较啰嗦。重写BaseExpandableListAdapter写的比较简洁,没看明白的朋友可以先到网上查下怎么自定义BaseExpandableListAdapter,和自定义BaseAdapter其实是一样的。
这个部分为转载,亲测实在是好用得不得了(偷笑)。
5、scrollerView嵌套ExpandableListView:
a、重写ExpandableListView
public class CustomExpandableListView extends ExpandableListView {
public CustomExpandableListView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
b、动态计算expandablelistview的高度,xxx_group.xml和xxx_child.xml的最外层要用linearlayout,反正relativelayout不行,不知道为什么
private void setListViewHeight(ExpandableListView listView) {
ListAdapter listAdapter = listView.getAdapter();
int totalHeight = 0;
int count = listAdapter.getCount();
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
c、较为复杂
public class ViewGroupForListView extends LinearLayout implements View.OnClickListener {
private ListAdapter mAdapter = null;
private OnItemClickListener mListener = null;
public ViewGroupForListView(Context context) {
super(context);
}
public ViewGroupForListView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
this.setOrientation(VERTICAL);
}
/**
* 绑定数据
*/
protected void bindData() {
int count = mAdapter.getCount();
for(int i = 0; i < count; i++) {
View v = mAdapter.getView(i, null, null);
v.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
v.setOnClickListener(this);
v.setId(i);
addView(v, i);
}
}
/**
* 设置adapter
* @param adapter
*/
public void setAdapter(ListAdapter adapter) {
mAdapter = adapter;
if(this.getChildCount() != 0) {
removeAllViews();
}
bindData();
}
/**
* 获取adapter
* @return
*/
public ListAdapter getAdapter() {
return mAdapter;
}
/**
* 绑定监听
* @param listener
*/
public void setOnItemClickListener(OnItemClickListener listener) {
this.mListener = listener;
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(mListener != null) {
mListener.onItemClick(v.getId(), mAdapter);
}
}
/**
* 监听接口
* @author Visual
*
*/
public interface OnItemClickListener {
public void onItemClick(int position, ListAdapter adapter);
}
相关文章推荐
- 关于css float
- js获取样式简洁版
- CSS中外边距叠加问题
- 用TextView显示时间(数码管样式)
- CSS3:radial-gradient,径向渐变的使用方法
- css中width和height默认值
- getComputedStyle与currentStyle获取样式(style/class)
- CSS样式覆盖规则
- 修改ActionBar样式小结
- CSS左侧固定宽 右侧自适应(兼容所有浏览器)
- 老生长谈:css实现右侧固定宽度,左侧宽度自适应
- Selenium - CSS Selector
- java 发送html格式邮件 样式混乱解决
- css盒模型
- css按钮模拟器
- CSS 注意事项
- 关于JAVA EE项目在WEB-INF目录下的jsp页面如何访问WebRoot中的CSS和JS文件
- css学习笔记20160115css语法格式选择器
- 【整理】HTML&CSS学习
- AlertDialog的样式修改