A Coisa Fica Preta
Embora isto seja documentado (e portanto é uma feature e não um bug), é bem provável que na sua primeira tentativa de usar um ListView você observe um efeito curioso: ao rolar a lista parte dela fica preta. Um efeito curioso, mas que inutiliza a sua lista (principalmente se o seu texto estiver em preto).
A explicação é que, por default, a ListView está otimizada para fundo preto. "Hello, Mr Google Engineer!": boas otimizações não impedem o funcionamento dos casos não otimizados!
A solução é simples (depois que você sabe): acrescente o parâmetro cacheColorHint na definição da ListView:
android:cacheColorHint="#00000000"
Usando Botões em Uma ListView
Uma vantagem de uma ListView é que você tem controle sobre os widgets usados para cada item. Você pode criar um layout para isto, de forma semelhante ao que faz para um intent. A coisa complica quando você resolve colocar no layout algum widget que gere um evento, como um botão.
O problema é que o listener do evento não tem, a princípio, como saber em qual item o evento foi disparado. Os widgets dos diversos itens são criados com o mesmo ID.
Eu achei uma solução complicada, que inclui até uma rotina recursiva. A ideia básica é colocar a identificação da linha no campo tag das views que a compõem. Fiz uma tentativa de mudar o ID dinamicamente, mas não funcionou. Eu acabei mantendo a rotina recursiva, mas aproveitei para associar também listeners ao botões:
public final class ClickableButtonListAdapter extends SimpleAdapter { public static final String HASHMAP_ID = "_id"; private OnClickListener[] btnListener; private int btnId[]; public ClickableButtonListAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) { super(context, data, resource, from, to); btnId = null; } // construtor com listas de ids dos botões e listeners associados public ClickableButtonListAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to, int[] btn, OnClickListener[] listener) { super(context, data, resource, from, to); btnListener = listener; btnId = btn; } @SuppressWarnings("unchecked") @Override public View getView(int position, View convertView, ViewGroup parent) { // Identifica os botões View view = super.getView(position, convertView, parent); String tag = ((HashMap<String, String>)getItem(position)).get(HASHMAP_ID); setViewTag(view, tag); // Associa os listeners if (btnId != null) { for (int i = 0; i < btnId.length; i++) { Button btn = (Button) view.findViewById(btnId[i]); if (btn != null) btn.setOnClickListener(btnListener[i]); } } } // Rotina auxiliar para identificar os elementos da lista private void setViewTag(View view, Object tag) { view.setTag(tag); if (view instanceof ViewGroup) { for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { setViewTag(((ViewGroup) view).getChildAt(i), tag); } } } }
Bonus: Como Limpar o Estado de um RadioButton
No meu caso, os botões nos itens do ListView eram radio buttons, isto é, um conjunto de botões onde, quando você marca um, os outros (do mesmo item) são automaticamente desmarcados. Existe, porém uma pequena limitação nos radio buttons do Android: não existe função para desmarcá-lo. Ou seja, uma vez que o operador fez uma seleção não teria como voltar a trás.
As solução é simples: acrescente mais um radio button ao grupo, mas deixe-o invisível. Para limpar os radio buttons do grupo, marque o invisível (isto você consegue fazer por programa).
Se eu tiver paciência coloco um exemplo de tudo isto no próximo post.
Nenhum comentário:
Postar um comentário