如何判断自定义expandablelisttview是否处于展开状态

ExpandableListView只展开一个group
在一个ExpandableListView,如何实现只展开一个group,方法如下:
mListView.setOnGroupExpandListener(new
OnGroupExpandListener() {
public void onGroupExpand(int groupPosition) {
// TODO Auto-generated method stub
for (int i = 0; i & mAdapter.getGroupCount(); i++) {
if (groupPosition != i) {
mListView.collapseGroup(i);
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。[android]在 ExpandableListView 的儿童复选框状态
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.
我读过约 30 页从等,以及有关跟踪列表中的复选状态教程但信息 (特别是工作信息) 是稀缺上在可展开 ListView 中这样做。
我有填充带复选框的儿童,但当我签上一个孩子从 1 组的一个框,在其他组中的随机儿童也检查。我要停止这。我觉得我读过的最佳信息是作为一个单独的标记设置复选框,但我不知道如何设置多个标记,当我试了,我比较 convertview 的复选框的类不匹配错误。
有人遇到过跟踪的复选框状态 expandablelistview 儿童的好方法吗?
所以我要把整个适配器的代码中,我做了多个更改。请检查 getGroupView 和整个 getChildView 的前几行,帮我看看我做错了。
编辑: 现在的情况,是当我选中一个复选框,然后展开另一个组,检查所有框取消选中:
public class MyExpandableListAdapter extends BaseExpandableListAdapter
implements OnCheckedChangeListener {
private Context mC
private ArrayList&ContactNameItems& mListDataH
private HashMap&String, List&ContactPhoneItems&& mListDataC
private boolean[] mGetC
private HashMap&String, boolean[]& mChildCheckS
private ArrayList&String& selectedN
private ChildViewHolder childViewH
private GroupViewHolder groupViewH
private String numberT
public MyExpandableListAdapter(Context context,
ArrayList&ContactNameItems& listDataHeader,
HashMap&String, List&ContactPhoneItems&& listDataChild,
ArrayList&String& listOfNumbers) {
mContext =
mListDataHeader = listDataH
mListDataChild = listDataC
selectedNumbers = listOfN
mChildCheckStates = new HashMap&String, boolean[]&();
public int getGroupCount() {
return mListDataHeader.size();
public ContactNameItems getGroup(int groupPosition) {
return mListDataHeader.get(groupPosition);
public long getGroupId(int groupPosition) {
return groupP
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
String contactName = getGroup(groupPosition).getName();
Bitmap contactImage = getGroup(groupPosition).getImage();
mGetChecked = new boolean[getChildrenCount(groupPosition)];
mChildCheckStates.put(contactName, mGetChecked);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.contact_name_item, null);
groupViewHolder = new GroupViewHolder();
groupViewHolder.mContactName = (TextView) convertView
.findViewById(R.id.lblListHeader);
groupViewHolder.mContactImage = (ImageView) convertView
.findViewById(R.id.ivContactPhoto);
convertView.setTag(groupViewHolder);
groupViewHolder = (GroupViewHolder) convertView.getTag();
if (contactImage != null) {
groupViewHolder.mContactImage.setImageBitmap(contactImage);
groupViewHolder.mContactImage
.setImageResource(R.drawable.default_contact);
groupViewHolder.mContactName.setText(contactName);
return convertV
public int getChildrenCount(int groupPosition) {
return mListDataChild.get(mListDataHeader.get(groupPosition).getName())
public ContactPhoneItems getChild(int groupPosition, int childPosition) {
return mListDataChild.get(mListDataHeader.get(groupPosition).getName())
.get(childPosition);
public long getChildId(int groupPosition, int childPosition) {
return childP
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
final String contactName = getGroup(groupPosition).getName();
final int mChildPosition = childP
numberText = getChild(groupPosition, childPosition).getNumber();
String typeText = getChild(groupPosition, childPosition).getPhoneType();
mGetChecked = mChildCheckStates.get(contactName);
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) this.mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.contact_detail_item, null);
childViewHolder = new ChildViewHolder();
childViewHolder.mPhoneNumber = (TextView) convertView
.findViewById(R.id.tv_phone_number);
childViewHolder.mPhoneType = (TextView) convertView
.findViewById(R.id.tv_phone_type);
childViewHolder.mCheckBox = (CheckBox) convertView
.findViewById(R.id.checkBox);
convertView.setTag(R.layout.contact_detail_item, childViewHolder);
childViewHolder = (ChildViewHolder) convertView
.getTag(R.layout.contact_detail_item);
childViewHolder.mPhoneNumber.setText(numberText);
childViewHolder.mPhoneType.setText(typeText);
childViewHolder.mCheckBox.setChecked(mGetChecked[mChildPosition]);
childViewHolder.mCheckBox.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
boolean isChecked = childViewHolder.mCheckBox.isChecked();
Log.d("Debug", "isChecked = " + String.valueOf(isChecked));
if (isChecked) {
selectedNumbers.add(numberText);
selectedNumbers.remove(numberText);
childViewHolder.mCheckBox.setChecked(isChecked);
mGetChecked[mChildPosition] = isC
mChildCheckStates.put(contactName, mGetChecked);
return convertV
public boolean isChildSelectable(int groupPosition, int childPosition) {
public boolean hasStableIds() {
public ArrayList&String& getSelectedNumbers() {
return selectedN
public final class GroupViewHolder {
TextView mContactN
ImageView mContactI
public final class ChildViewHolder {
TextView mPhoneN
TextView mPhoneT
CheckBox mCheckB
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
Log.d("Debug", "onCheckChangedListener : " + String.valueOf(isChecked));
解决方法 1:
我看到你有 selectedNumbers 对象,那是何种类型的集合吗?它可能会使最有意义,有一张地图或列表或一些集合的基础更多独特的东西,像组和儿童的立场。然后你可以这样做:
(编辑: 编辑代码,以确保 checkedChangedListener 不会触发) (编辑 2 基于 OP 的更新): 你大概不应该使用的布尔值数组的字符串的地图。而是尝试此操作。是相当类似,但它使用的将是更加万无一失,比较比字符串的整数
HashMap&Integer, Integer& mCheckedS // assume initialized as you did
childViewHolder.mPhoneNumber.setText(numberText);
childViewHolder.mPhoneType.setText(typeText);
childViewHolder.mCheckBox.setOnCheckedChangeListener(null);
if (mCheckedStates.contains(groupPosition)) {
int checkedChildren = mCheckedStates.get(groupPosition);
if ((checkedChildren & (1 && childPosition)) ==
childViewHolder.mCheckBox.setChecked(true);
//Edit: Cannot rely on checkbox being false on Recycle,
childViewHolder.mCheckBox.setChecked(false);
childViewHolder.mCheckBox.setOnCheckedChangeListener(this);
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// get group and child positions
if (isChecked) {
if (mCheckedStates.contains(groupPosition)) {
// I'm using a bitmap to keep resources low, but it's not necessary to do it this way
int childmap = mCheckedStates.get(groupPosition);
childmap += (1 && childPosition);
mCheckedStates.put(groupPosition, childmap);
mCheckedStates.put(groupPosition, (1 && childPosition));
if (mCheckedStates.contains(groupPosition)) {
int childmap = mCheckedStates.get(groupPosition);
if (childmap == (1 && childPosition)) {
mCheckedStates.remove(groupPosition);
childmap &= ~(1 && childPosition);
mCheckedStates.put(groupPosition, childmap);33899人阅读
Android View效果和功能(50)
Activity及组件(39)
1. 设置ExpandableListView 默认是展开的:&
先实例化exListView 然后&
exListView.setAdapter(exlvAdapter);
//遍历所有group,将所有项设置成默认展开
intgroupCount = exListView.getCount();
for (inti=0; i&groupC i++)
exListView.expandGroup(i);
2. 去掉ExpandableListView 默认的箭头&
用到ExpandableListView时有个箭头图标系统自带的在你自定义布局也不能去掉只要设置一个属性即可,如下:&
settingLists.setGroupIndicator(null); ~~~~~~~~~~~~~~~~~此处就是设置自定义的箭头图标的。置空则没有了。 &
也可以自定义(但是位置还是在那个地方不推荐)如下:&
首先,自定义一个expandablelistviewselector.xml文件,具体内容如下: Java代码&
&?xml version=&1.0& encoding=&utf-8&?&
&selector xmlns:android=&/apk/res/android&&
&item android:state_expanded=&true& android:drawable=&@drawable/expandablelistviewindicatordown& /&
&item android:drawable=&@drawable/expandablelistviewindicator& /&
&/selector&
加一句代码如下:&
settingLists.setGroupIndicator(this.getResources().getDrawable(R.layout.expandablelistviewselector));
或xml设置:
android:groupIndicator=&@drawable/groupIndicator_selector&
3. 将默认的箭头修改到右边显示:&
1首先ExpandableListV &
elistview.setGroupIndicator(null);//将控件默认的左边箭头去掉,
&2在自定义的继承自BaseExpandableListAdapter的adapter中有一个方法
/** * 父类view */ @Override
public View getGroupView(intgroupPosition, booleanisExpanded, View convertView, ViewGroup parent)
{ Log.i(&zhaoxiong&,&parent view&);
LinearLayoutparentLayout=(LinearLayout) View.inflate(context, R.layout.wowocoupons_parent_item, null);
TextViewparentTextView=(TextView)parentLayout.findViewById(R.id.parentitem);
parentTextView.setText(parentlist.get(groupPosition));
ImageViewparentImageViw=(ImageView) parentLayout.findViewById(R.id.arrow);
//判断isExpanded就可以控制是按下还是关闭,同时更换图片
if(isExpanded){
parentImageViw.setBackgroundResource(R.drawable.arrow_down);
parentImageViw.setBackgroundResource(R.drawable.arrow_up); }
return parentL
expandablelistview响应onGroupClick监听:设置expandablelistview.setOnGroupClickListener()
折叠和展开事件,可以设置setOnGroupCollapseListener和setOnGroupExpandListener
ExpandableListView中包含多个group,想要展开一个group时,其他group都关闭:
exList.setOnGroupExpandListener(new OnGroupExpandListener() {
public void onGroupExpand(int groupPosition) {
for (int i = 0; i & getData().size(); i++) {
if (groupPosition != i) {
exList.collapseGroup(i);
3.expandablelistview的Group点击事件,onGroupClick的返回值false展开,true不展开
tt_list.setOnGroupClickListener(new OnGroupClickListener() {
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
if(adapter.getGroupData().get(groupPosition).getList().size()==1){
Bundle b=new Bundle();
b.putInt(&saveIndex&, 0);
b.putString(&mac&, mac);
b.putString(&deviceId&, mDeviceId);
b.putSerializable(&datalist&, adapter.getGroupData().get(groupPosition).getList());
Intent i=new Intent(WappushBindingActivity.this,VideoPlayerActivity.class);
i.putExtras(b);
startActivity(i);
int groupCount = tt_list.getCount();
for (int i=0; i&groupC i++){
if(i!=GroupPosition)
tt_list.collapseGroup(i);
Log.v(&xulongheng*WappushBind*tt_list&, &onGroupClick:&+previousX+&/&+previousY);
//默认为false,设为true时,点击事件不会展开Group
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1111988次
积分:10749
积分:10749
排名:第1002名
原创:162篇
转载:212篇
评论:141条
(4)(4)(2)(2)(3)(2)(10)(1)(1)(1)(3)(1)(1)(7)(8)(7)(7)(1)(1)(14)(14)(2)(1)(8)(50)(6)(3)(11)(23)(25)(14)(7)(29)(24)(25)(20)(27)(9)Android的ExpandableListView的动画展开效果和使用traceview的性能优化
Android的ExpandableListView的动画展开效果和使用traceview的性能优化
解决方案Github pull request链接:/idunnololz/AnimatedExpandableListView/pull/30
Android的原生提供和展开分组的ListView:ExpandableListView,然而相比于iOS上原生提供的UITableView,其UI能力不足,比如没有原生的动画展开和收起效果支持。
在开源代码社区我们可以找到几个为Android的ExpandableListView添加的动画解决方案。其中idunnololz的AnimatedExpandableListView是不错的方案之一。
(/idunnololz/AnimatedExpandableListView)。它的优点:性能较好,提供源代码而不是library(这点很重要),注释清晰。
然而性能的优化是没有止境的,当分组内的子view(childView)变得复杂,或者ListView的parent结构复杂,例如内嵌于其它LinearLayout, FrameLayout或者ScrollView之中,并且parent使用重写的onMeasure()方法时,生成childView的效率就有可能大大影响应用的性能。
合理使用AnimatedExpandableListView的关键是在于AnimatedExpandableListView#getRealChildView()的实现,这是应用开发的责任。实际项目中,通过优化getRealChildView(),动画效果的启动时间从1340ms减少到了680ms (展开一个含有5个子项目的分组),优化比例超过50%。而发现的问题的定位和解决方案,基本是用过使用Android提供的method tracing方法(android.os.Debug.startMethodTraceing)进行分析。
优化前的getRealChildView()实现,需要大量的view初始化,因为没有可用的convertView,而事实上,在动画绘制阶段时生成的childView完全可以被重用,即使convertView并没有被Android Framework给出。如下面的traceview profile看到的,优化前,getChildView()消耗了超过1秒的时间。
优化后的性能:getChildView耗时从1340ms下降到678ms。
这是如何做到的呢?这需要我们再研究一下动画展开的原理,也就是分析getChildView()里面耗时最长的那些动作。首先排除其他因素的影响,专注于AnimatedExpandableList本身的逻辑,我们使用GitHub上原生提供的Example来做分析:这是展开5个子项目的分组的情况,注意5个子分组的view生成,LayoutInflater.inflate被执行了10次,是其两倍。而inflate是相当耗时的。有没有方法来减少这部分工作消耗呢?
方法是使用Android推荐的LRU cache来保存childView的。关于LruCache,请见Android的reference documents和training。这里特别要注意的是,childView在dataSet改变时需要重新生成,而不是在cache中获得,这里使用的方法是判断childView的type。在自己的项目中需要根据情况认真考虑dataSet改变如何更新cache的问题。效果如下所示:inflate的次数减少到5次,一次都不浪费。消耗时间从160ms降低到80ms。
代码还是最直观说明问题的:
public class MainActivity extends Activity {
private class ExampleAdapter extends AnimatedExpandableListAdapter {
private LruCache&Long, View&
public View getRealChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
ChildItem item = getChild(groupPosition, childPosition);
if (convertView == null) {
// when convertView is not given, we try using view from cache.
// Note: check the view type to ensure it's really resuable.
Long key = ((long)groupPosition && 32) + childP
View view = vcache.get(key);
if (view != null && view.getTag() != null) {
holder = (ChildHolder) view.getTag();
if (holder.type == getRealChildType(groupPosition, childPosition) ) {
convertView =
Log.d(TAG, &getRealChildView: & + groupPosition + & & + childPosition + & & + &Got Cache!&);
holder = new ChildHolder();
convertView = inflater.inflate(R.layout.list_item, parent, false);
holder.title = (TextView) convertView.findViewById(R.id.textTitle);
holder.hint = (TextView) convertView.findViewById(R.id.textHint);
convertView.setTag(holder);
vcache.put(key, convertView);
Log.d(TAG, &getRealChildView: & + groupPosition + & & + childPosition + & & + &No Cache!&);
holder = (ChildHolder) convertView.getTag();
holder.title.setText(item.title);
holder.hint.setText(item.hint);
return convertV
我的热门文章
即使是一小步也想与你分享android之ExpandableListView 无法展开 - 推酷
android之ExpandableListView 无法展开
对,没错,就是这个button组件,不知道出现都少次过问题,很多都是它造成的!
最常见的问题:ExpandableListView无法展开,OnItemClickListener不响应等问题。
解决办法:检查在getView方法中加载的视图文件,是否含有Button或者ImageButton,如果含有,把它改成TextView或者ImageView试试,可能问题就解决。
原因:布局文件的监听事件顺序是组件视图,然后才是布局文件本事,而像OnItemClickListener这样的监听事件,都是监听的布局,如果上面有了Button这样的,就会被拦截而监听不到了。
自己定义好了布局视图,带有箭头,但显示出来的还有其系统自带的箭头。
问题:去掉系统箭头显示。
解决办法:在ExpandableListView属性中增加android:groupIndicator=&@null&
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致}

我要回帖

更多关于 expandablelist 展开 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信