ExpandableListView: ocultar indicador para grupos sin elementos secundarios

108

De una manera ExpandableListView, ¿hay alguna forma de ocultar el indicador de grupo para grupos sin niños?

Gratzi
fuente
1
Para aclarar: ¿Hay alguna forma de ocultar el indicador de grupo SOLO para grupos sin niños?
AlleyOOP

Respuestas:

111

Prueba esto >>>

para todos los artículos

 getExpandableListView().setGroupIndicator(null);

En xml

android:groupIndicator="@null"
Amt87
fuente
40
Creo que establecerá el groupIndicator para todos los elementos y no solo para aquellos sin niños.
ericosg
4
Probado y no funciona. Este simple ocultar todos los indicadores tiene hijos o no.
viernes
2
myExpandableListView.setGroupIndicator (nulo); funciona para mí
Ranjith Kumar
@ericosg ¿hay alguna forma de ocultar el indicador para grupos sin niños?
KJEjava48
1
Oculta todos los indicadores, no los que no tienen hijo.
Sam
88

La android:groupIndicatorpropiedad toma un estado habilitado para dibujar. Es decir, puede establecer una imagen diferente para diferentes estados.

Cuando el grupo no tiene hijos, el estado correspondiente es 'state_empty'

Vea estos enlaces de referencia:

esto y esto

Para state_empty, puede establecer una imagen diferente que no sea confusa, o simplemente usar color transparente para no mostrar nada ...

Agregue este elemento en su dibujo con estado junto con otros ...

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

Entonces, su lista de estado puede ser así:

<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>

En caso de que esté utilizando una ExpandableListActivity, puede configurar el indicador de grupo en onCreate de la siguiente manera:

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

He probado que esto funciona.

Sarwar Erfan
fuente
36
No funciona: probado en Android 4.0.2 (ICS). Vea otras respuestas a esta pregunta en esta página. Parece que Android considera que el grupo no expandido está vacío. Simplemente configure el indicador de grupo en transparente, luego agregue un imageView a su fila de grupo y en el método de adaptador getGroupView, configúrelo en el ícono que desee.
Fraggle
1
Este código tampoco funciona conmigo (probado en Android 4.4). El grupo no expandido se considera vacío (sin hijos), por lo que el icono está configurado en color / transparente.
Guicara
1
Gracias por el código, pero parece una broma: ¿código tan complejo para una tarea tan simple?
Antonio Sesto
1
¡Es difícil de creer que esta respuesta haya recibido tantos 'útiles' y una recompensa mientras está documentado que los grupos colapsados ​​se consideran vacíos por razones de rendimiento!
3c71
41

Según la respuesta de StrayPointer y el código del blog, puede simplificar el código aún más:

En su xml agregue lo siguiente a ExpandableListView:

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

Luego, en el Adaptador, haga lo siguiente:

@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 );
    }
}

Al usar el método setImageResource, lo hace todo con una sola línea. No necesita las tres matrices Integer en su adaptador. Tampoco necesita un selector XML para estado expandido y contraído. Todo se hace a través de Java.

Además, este enfoque también muestra el indicador correcto cuando un grupo se expande de forma predeterminada lo que no funciona con el código del blog.

Jenzz
fuente
4
Esto está destinado a ser utilizado en el getGroupView()método de su BaseExpandableListAdapterimplementación. Eche un vistazo a esta implementación de ejemplo .
jenzz
5
@jenzz ¿Qué es el "indicador"?
IBunny
Él usó el ViewHolderpatrón. indicatores el nombre de la variable del titular de la vista.
Guicara
El indicador es una vista de imagen La imagen que desea mostrar en función de los estados
Ojonugwa Jude Ochalifu
indicador se refiere a explist_indicator Imageview en group_row xml: <? xml?> <LinearLayout android: Orientación = "horizontal" android: layout_height = "wrap_content" android: layout_width = "fill_parent"> <ImageView android: layout_height = "20px" android : layout_width = "20px" android: id = "@ + id / explist_indicator" android: src = "@ drawable / expander_group" /> <TextView android: layout_height = "wrap_content" android: layout_width = "fill_parent" android: id = " @ + id / groupname "android: paddingLeft =" 30px "android: textStyle =" bold "android: textSize =" 16px "/> </LinearLayout>
Razvan_TK9692
26

Como se menciona en una respuesta diferente, dado que Android trata un grupo de lista no expandido como vacío, el icono no se dibuja incluso si el grupo tiene hijos.

Este enlace me solucionó el problema: http://mylifewithandroid.blogspot.com/2011/06/hiding-group-indicator-for-empty-groups.html

Básicamente, debe establecer el elemento de diseño predeterminado como transparente, mover el elemento de diseño a la vista de grupo como ImageView y alternar la imagen en su adaptador.

StrayPointer
fuente
12

En su código, simplemente use el xml personalizado para la lista de grupos y en eso coloque ImageView para GroupIndicator .

Y agregue las siguientes matrices en su 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
};

también en el método ExpandableListAdapter agregue las mismas cosas que a continuación

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;
}

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

Mihir Trivedi
fuente
10

En XML

android:groupIndicator="@null"

En ExpandableListAdapter-> getGroupViewcopiar el siguiente código

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);
      }
}
Saurabh Agarwal
fuente
1
¿Cómo utilizar los elementos de diseño DEFAULT? Dice: No se puede resolver el símbolo 'agrupar'
StNickolay
4

te sugiero mi solución:

1) Borrar el indicador de grupo predeterminado:

<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) en 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;
}
Evgeny Karavashkin
fuente
@ stackoverflow.com/users/4090796/evgeny-karavashkin ¿qué es "arrowup"?
StNickolay
2

Solo quería mejorar la respuesta de Mihir Trivedi. Puede colocar esto dentro de getGroupView () que está dentro de la clase MyExpandableListAdapter

    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]);
            }
        }
    }

... y en cuanto a la vista de diseño, así es como parece ser mi group_items.xml

<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"/>

Espero que eso ayude ... recuerda dejar un voto a favor

keyboard_kracker22
fuente
1

Use esto, funciona perfectamente para mí.

<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>
Asad Rao
fuente
¿Podría publicar también su código ExpandableListView? Esto no me funciona (el group_indicator aparece para grupos con y sin niños).
1

¿Ha intentado cambiar ExpandableListViewel atributo de android:groupIndicator="@null"?

Rajat Gupta
fuente
0

Simplemente, crea un nuevo diseño xml con altura = 0 para el encabezado del grupo oculto. Por ejemplo, es '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>

Entonces el diseño de encabezado de su grupo normal es '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>

Finalmente, simplemente actualice el método getGroupView en su clase de adaptador:

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;
        }
    }
}

IMPORTANTE : La etiqueta raíz de los archivos de diseño (oculta y normal) debe ser diferente (como en el ejemplo anterior, LinearLayout y RelativeLayout)

Tran Hieu
fuente
-3

convertView.setVisibility (View.GONE) debería hacer el truco.

@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);
        }
Vadym Vikulin
fuente
3
Esto simplemente elimina todos los elementos: La lista está vacía -> yo está triste :(
Ich
¿Ha agregado un cheque de contador? if (getChildrenCount (groupPosition) == 0) {
Vadym Vikulin