ExpandableListView - hide indicator for groups with no children

AndroidAndroid ListviewExpandablelistview

Android Problem Overview


In an ExpandableListView, is there a way to hide the group indicator for groups with no children?

Android Solutions


Solution 1 - Android

Try this >>>

for all items

 getExpandableListView().setGroupIndicator(null);

In xml

android:groupIndicator="@null"

Solution 2 - Android

The android:groupIndicator property takes a state enabled drawable. That is, you can set different image for different states.

When the group has no children, the corresponding state is 'state_empty'

See these reference links:

this and this

For state_empty, you can set a different image which is not confusing, or, simply use transparent color to display nothing...

Add this item in your stateful drawable along with others....

<item android:state_empty="true" android:drawable="@android:color/transparent"/>

So, your statelist can be like this:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
 	<item android:state_empty="true" android:drawable="@android:color/transparent"/>
	<item android:state_expanded="true" android:drawable="@drawable/my_icon_max" />
 	<item android:drawable="@drawable/my_icon_min" />
</selector>

In case you are using an ExpandableListActivity, you can set the groupindicator in onCreate as follows:

getExpandableListView().setGroupIndicator(getResources().getDrawable(R.drawable.my_group_statelist));

I have tested this to be working.

Solution 3 - Android

Based on StrayPointer's answer and the code from the blog, you can simplify the code even more:

In your xml add the folowing to ExpandableListView:

android:groupIndicator="@android:color/transparent"

Then in the Adapter you do the following:

@Override
protected void bindGroupView(View view, Context paramContext, Cursor cursor, boolean paramBoolean){
    **...**

 	if ( getChildrenCount( groupPosition ) == 0 ) {
       indicator.setVisibility( View.INVISIBLE );
	} else {
	   indicator.setVisibility( View.VISIBLE );
	   indicator.setImageResource( isExpanded ? R.drawable.list_group_expanded : R.drawable.list_group_closed );
	}
}

By using the setImageResource method you get it all done with a one-liner. You do not need the three Integer arrays in your adapter. You also do not need an XML selector for state expanded and collapsed. All is done via Java.

Plus, this approach also displays the correct indicator when a group is expanded by default what does not work with the code from the blog.

Solution 4 - Android

As mentioned in a different answer, since Android treats an un-expanded list group as empty, the icon is not drawn even if the group has children.

This link solved the problem for me: http://mylifewithandroid.blogspot.com/2011/06/hiding-group-indicator-for-empty-groups.html

Basically you have to set the default drawable as transparent, move the drawable into your group view as an ImageView and toggle the image in your adapter.

Solution 5 - Android

In XML

android:groupIndicator="@null"

In ExpandableListAdapter -- > getGroupView copy following code

if (this.mListDataChild.get(this.mListDataHeader.get(groupPosition)).size() > 0){
      if (isExpanded) {
          arrowicon.setImageResource(R.drawable.group_up);
      } else {
          arrowicon.setImageResource(R.drawable.group_down);
      }
}

Solution 6 - Android

In your code just use the custom xml for group list and in that put the ImageView for GroupIndicator.

And Add below arrays in your ExpandableListAdapter

private static final int[] EMPTY_STATE_SET = {};
private static final int[] GROUP_EXPANDED_STATE_SET = { android.R.attr.state_expanded };
private static final int[][] GROUP_STATE_SETS = { EMPTY_STATE_SET, // 0
GROUP_EXPANDED_STATE_SET // 1
};

also in ExpandableListAdapter's method add same things as below

public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) 
{ 
    if (convertView == null) 
    {
        LayoutInflater infalInflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.row_group_list, null);
    }
    
    //Image view which you put in row_group_list.xml
    View ind = convertView.findViewById(R.id.iv_navigation);
	if (ind != null)
	{
		ImageView indicator = (ImageView) ind;
		if (getChildrenCount(groupPosition) == 0) 
		{
			indicator.setVisibility(View.INVISIBLE);
		} 
		else 
		{
			indicator.setVisibility(View.VISIBLE);
			int stateSetIndex = (isExpanded ? 1 : 0);
			Drawable drawable = indicator.getDrawable();
			drawable.setState(GROUP_STATE_SETS[stateSetIndex]);
		}
    }
 
    return convertView;
}

Reference: http://mylifewithandroid.blogspot.in/2011/06/hiding-group-indicator-for-empty-groups.html

Solution 7 - Android

this could be another way from XML, set android:groupIndicator="@null"

Reference Link: https://stackoverflow.com/a/5853520/2624806

Solution 8 - Android

suggest you my solution:

1)Clear default groupIndicator :

<ExpandableListView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"       
    android:layout_width="wrap_content"
    android:layout_height="240dp"        
    android:layout_gravity="start"
    android:background="#cccc"  
    android:groupIndicator="@android:color/transparent"     
    android:choiceMode="singleChoice"
    android:divider="@android:color/transparent"        
    android:dividerHeight="0dp"  
     />

2) in ExpandableAdapter:

@Override
public View getGroupView(int groupPosition, boolean isExpanded,
		View convertView, ViewGroup parent) {
	if (convertView == null) {
		convertView = new TextView(context);
	}
	((TextView) convertView).setText(groupItem.get(groupPosition));		
	((TextView) convertView).setHeight(groupHeight);
	((TextView) convertView).setTextSize(groupTextSize);
	
    //create groupIndicator using TextView drawable
	if (getChildrenCount(groupPosition)>0) {
		Drawable zzz ;
		if (isExpanded) {
			zzz = context.getResources().getDrawable(R.drawable.arrowup);
		} else {
			zzz = context.getResources().getDrawable(R.drawable.arrowdown);
		}								
		zzz.setBounds(0, 0, groupHeight, groupHeight);
		((TextView) convertView).setCompoundDrawables(null, null,zzz, null);
	}		
	convertView.setTag(groupItem.get(groupPosition));		
	
	return convertView;
}

Solution 9 - Android

Just wanted to improve on Mihir Trivedi's answer. You can place this within getGroupView() that's inside MyExpandableListAdapter class

    View ind = convertView.findViewById(R.id.group_indicator);
    View ind2 = convertView.findViewById(R.id.group_indicator2);
    if (ind != null)
    {
        ImageView indicator = (ImageView) ind;
        if (getChildrenCount(groupPosition) == 0)
        {
            indicator.setVisibility(View.INVISIBLE);
        }
        else
        {
            indicator.setVisibility(View.VISIBLE);
            int stateSetIndex = (isExpanded ? 1 : 0);
            
            /*toggles down button to change upwards when list has expanded*/
            if(stateSetIndex == 1){
                ind.setVisibility(View.INVISIBLE);
                ind2.setVisibility(View.VISIBLE);
                Drawable drawable = indicator.getDrawable();
                drawable.setState(GROUP_STATE_SETS[stateSetIndex]);
            }
            else if(stateSetIndex == 0){
                ind.setVisibility(View.VISIBLE);
                ind2.setVisibility(View.INVISIBLE);
                Drawable drawable = indicator.getDrawable();
                drawable.setState(GROUP_STATE_SETS[stateSetIndex]);
            }
        }
    }

...and as for the layout view, this is how my group_items.xml appears to be

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
    android:id="@+id/group_heading"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:paddingLeft="20dp"
    android:paddingTop="16dp"
    android:paddingBottom="16dp"
    android:textSize="15sp"
    android:textStyle="bold"/>

<ImageView
    android:id="@+id/group_indicator"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@android:drawable/arrow_down_float"
    android:layout_alignParentRight="true"
    android:paddingRight="20dp"
    android:paddingTop="20dp"/>

<ImageView
    android:id="@+id/group_indicator2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@android:drawable/arrow_up_float"
    android:layout_alignParentRight="true"
    android:visibility="gone"
    android:paddingRight="20dp"
    android:paddingTop="20dp"/>

Hope that helps...remember to leave an upvote

Solution 10 - Android

Use this it is perfectly working for me.

<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:drawable="@drawable/group_indicator_expanded" android:state_empty="false" android:state_expanded="true"/>
<item android:drawable="@drawable/group_indicator" android:state_empty="true"/>
<item android:drawable="@drawable/group_indicator"/>

</selector>

Solution 11 - Android

Have you tried to change ExpandableListView's attribute android:groupIndicator="@null"?

Solution 12 - Android

Simply, you create a new xml layout with height=0 for the hidden group header. For example, it's 'group_list_item_empty.xml'

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"              
              android:layout_width="match_parent"
              android:layout_height="0dp">
</RelativeLayout>

Then your normal group header layout is 'your_group_list_item_file.xml'

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="48dp"
              android:orientation="horizontal">
	...your xml layout define...
</LinearLayout>

Finally, you just update the getGroupView method in your Adapter Class:

public class MyExpandableListAdapter extends BaseExpandableListAdapter{   
    
	//Your code here ...
	
	@Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup viewGroup) {
        if (Your condition to hide the group header){
        	if (convertView == null || convertView instanceof LinearLayout) {
        		LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
	            convertView = mInflater.inflate(R.layout.group_list_item_empty, null);
        	}        	
        	return convertView;
        }else{	    
	        if (convertView == null || convertView instanceof RelativeLayout) {
	            LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
	            convertView = mInflater.inflate(R.layout.your_group_list_item_file, null);	            
	        }	
			//Your code here ...
	        return convertView;
        }
    }
}

IMPORTANT: The root tag of the layout files (hidden and normal) must be different (as above example, LinearLayout and RelativeLayout )

Solution 13 - Android

The answers posted around here will make your group indicator gone even when a group has children.

To solve this, override the group indicator.

First, set your group indicator as null:

    ExpandableListView.setGroupIndicator(null);

Then, go to your xml that contains the header, and add an ImageView with your drawable.

After that, go to your ExpandableListAdapter.java, and in the "getGroupView" section, do the following:

public View getGroupView(int groupPosition, boolean isExpanded,
                         View convertView, ViewGroup parent) {
    String headerTitle = (String) getGroup(groupPosition);
    if (convertView == null) {
        LayoutInflater infalInflater = (LayoutInflater) this._context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.list_group, null);
    }

    TextView lblListHeader = convertView
            .findViewById(R.id.lblListHeader); // this is your header

    ImageView groupIndicator = convertView.findViewById(R.id.group_indicator); // this is the ImageView included in your xml to override the indicator

    if (getChildrenCount(groupPosition) == 0) {
        convertView.setVisibility(View.GONE);
        lblListHeader.setVisibility(View.GONE);
        convertView.setPadding(0,0,0,0); //try not to include padding on your xml, and instead define the padding here.

    } else {
        convertView.setVisibility(View.VISIBLE);
        convertView.setPadding(8,8,8,0);
        lblListHeader.setVisibility(View.VISIBLE);
        lblListHeader.setTypeface(font);
        lblListHeader.setText(headerTitle);
        if (isExpanded) { //this is the part where we define our group indicator based on the expanded status of the adapter
            groupIndicator.setImageResource(R.drawable.group_indicator_expanded);
        } else {
            groupIndicator.setImageResource(R.drawable.group_indicator_empty);
        }
    }

    return convertView;
}

Solution 14 - Android

convertView.setVisibility(View.GONE) should do the trick.

@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
    DistanceHolder holder;
    if (convertView == null) {
        convertView = LayoutInflater.from(context).inflate(R.layout.list_search_distance_header, parent, false);
        if (getChildrenCount(groupPosition)==0) {
            convertView.setVisibility(View.GONE);
        }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGratziView Question on Stackoverflow
Solution 1 - AndroidAmt87View Answer on Stackoverflow
Solution 2 - AndroidSarwar ErfanView Answer on Stackoverflow
Solution 3 - AndroidjenzzView Answer on Stackoverflow
Solution 4 - AndroidStrayPointerView Answer on Stackoverflow
Solution 5 - AndroidSaurabh AgarwalView Answer on Stackoverflow
Solution 6 - AndroidMihir TrivediView Answer on Stackoverflow
Solution 7 - AndroidCoDeView Answer on Stackoverflow
Solution 8 - Android Evgeny KaravashkinView Answer on Stackoverflow
Solution 9 - Androidkeyboard_kracker22View Answer on Stackoverflow
Solution 10 - AndroidAsad RaoView Answer on Stackoverflow
Solution 11 - AndroidRajat GuptaView Answer on Stackoverflow
Solution 12 - AndroidTran HieuView Answer on Stackoverflow
Solution 13 - AndroidggaribottoView Answer on Stackoverflow
Solution 14 - AndroidVadym VikulinView Answer on Stackoverflow