ExpandableListView - indicador de ocultar para grupos sem filhos

108

Em um ExpandableListView, existe uma maneira de ocultar o indicador de grupo para grupos sem filhos?

Gratzi
fonte
1
Para esclarecer: Existe uma maneira de ocultar o indicador de grupo SOMENTE para grupos sem crianças?
AlleyOOP

Respostas:

111

Experimente >>>

para todos os itens

 getExpandableListView().setGroupIndicator(null);

Em xml

android:groupIndicator="@null"
Amt87
fonte
40
Acredito que definirá o groupIndicator para todos os itens e não apenas para aqueles sem filhos.
Ericosg
4
Testado e não funciona. Este simples ocultar todos os indicadores tem filhos ou não.
frusso
2
myExpandableListView.setGroupIndicator (null); funciona para mim
Ranjith Kumar
@ericosg existe alguma maneira de ocultar o indicador para grupos sem filhos ??
KJEjava48
1
Ele oculta todos os indicadores, não aqueles sem filhos.
Sam,
88

o android:groupIndicator propriedade tem um drawable habilitado para o estado. Ou seja, você pode definir imagens diferentes para estados diferentes.

Quando o grupo não tem filhos, o estado correspondente é 'state_empty'

Veja estes links de referência:

isso e isso

Para state_empty , você pode definir uma imagem diferente que não seja confusa, ou simplesmente usar a cor transparente para não exibir nada ...

Adicione este item em seu drawable com monitoração de estado junto com outros ....

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

Então, sua lista de estatísticas pode ser assim:

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

Caso você esteja usando uma ExpandableListActivity, você pode definir o groupindicator em onCreate da seguinte maneira:

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

Eu testei isso para funcionar.

Sarwar Erfan
fonte
36
Não funciona: testado em Android 4.0.2 (ICS). Veja outras respostas a esta pergunta nesta página. Parece que o Android considera o grupo não expandido como vazio. Basta definir o indicador de grupo como transparente, adicionar imageView à linha do grupo e, no método getGroupView do adaptador, definir o ícone desejado.
Fraggle
1
Este código também não funciona comigo (testado no Android 4.4). O grupo não expandido é considerado vazio (sem filhos), então o ícone é definido como colorido / transparente.
Guicara
1
Obrigado pelo código, mas parece uma piada: código tão complexo para uma tarefa tão simples?
Antonio Sesto
1
Difícil de acreditar que esta resposta recebeu tantos 'úteis' e uma recompensa enquanto está documentado que grupos colapsados ​​são considerados vazios por motivos de desempenho!
3c71
41

Com base na resposta de StrayPointer e no código do blog, você pode simplificar ainda mais o código:

Em seu xml, adicione o seguinte a ExpandableListView:

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

Em seguida, no Adaptador, você faz o seguinte:

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

Usando o método setImageResource, você faz tudo com uma linha. Você não precisa dos três arrays Integer em seu adaptador. Você também não precisa de um seletor XML para estado expandido e recolhido. Tudo é feito via Java.

Além disso, essa abordagem também exibe o indicador correto quando um grupo é expandido por padrão, o que não funciona com o código do blog.

Jenzz
fonte
4
Isso deve ser usado no getGroupView()método de sua BaseExpandableListAdapterimplementação. Dê uma olhada neste exemplo de implementação .
jenzz
5
@jenzz O que é o "indicador"?
IBunny
Ele usa o ViewHolderpadrão. indicatoré o nome da variável do titular da visualização.
Guicara
O indicador é uma visualização de imagem. A imagem que você deseja exibir com base nos estados
Ojonugwa Jude Ochalifu
indicador refere-se ao explist_indicator Imageview no group_row xml: <? xml?> <LinearLayout android :idance = "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

Conforme mencionado em uma resposta diferente, como o Android trata um grupo de lista não expandida como vazio, o ícone não é desenhado mesmo se o grupo tiver filhos.

Este link resolveu o problema para mim: http://mylifewithandroid.blogspot.com/2011/06/hiding-group-indicator-for-empty-groups.html

Basicamente, você deve definir o drawable como transparente, mover o drawable para a visualização de grupo como ImageView e alternar a imagem em seu adaptador.

StrayPointer
fonte
12

Em seu código apenas use o xml customizado para lista de grupos e nele coloque o ImageView para GroupIndicator .

E adicione as matrizes abaixo em seu 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
};

também no método ExpandableListAdapter, adicione as mesmas coisas que abaixo

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

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

Mihir Trivedi
fonte
10

Em XML

android:groupIndicator="@null"

Em ExpandableListAdapter-> getGroupViewcopiar o seguinte 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
fonte
1
Como usar drawables DEFAULT? Diz: Não é possível resolver o símbolo 'agrupamento'
StNickolay
4

sugiro minha solução:

1) Limpar groupIndicator padrão:

<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) em 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
fonte
2

Só queria melhorar a resposta de Mihir Trivedi. Você pode colocá-lo em getGroupView () que está dentro da classe 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]);
            }
        }
    }

... e quanto à visualização do layout, é assim que meu group_items.xml parece ser

<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 ajude ... lembre-se de deixar um voto positivo

keyboard_kracker22
fonte
1

Use isso está funcionando perfeitamente para mim.

<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
fonte
Você poderia postar seu código ExpandableListView também? Isso não está funcionando para mim (o group_indicator aparece para grupos com e sem filhos).
1

Você já tentou alterar ExpandableListViewo atributo de android:groupIndicator="@null"?

Rajat Gupta
fonte
0

Simplesmente, você cria um novo layout xml com altura = 0 para o cabeçalho do grupo oculto. Por exemplo, é '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>

Então, o layout normal do cabeçalho do grupo é '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>

Por fim, basta atualizar o método getGroupView em sua classe 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 : A tag raiz dos arquivos de layout (oculto e normal) deve ser diferente (como exemplo acima, LinearLayout e RelativeLayout)

Tran Hieu
fonte
-3

convertView.setVisibility (View.GONE) deve fazer o truque.

@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
fonte
3
Isso apenas remove todos os itens: A lista está vazia -> eu estou triste :(
Ich
você adicionou cheque de contador? if (getChildrenCount (groupPosition) == 0) {
Vadym Vikulin