Abaixo está um trecho de código com um ListView. Eu adicionei um emptyView e um headerView. Adicionar headerView faz com que a posição em onItemClick seja aumentada em um.
Portanto, sem headerView o primeiro elemento da lista teria a posição 0, com headerView a posição do primeiro elemento da lista seria 1!
Isso causa erros em meu adaptador, por exemplo, ao chamar getItem () e usar alguns outros métodos, veja abaixo. Coisa estranha: no método getView () do adaptador, o primeiro elemento da lista é solicitado com a posição 0, mesmo se headerView for adicionado !!
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ListView list = (ListView) viewSwitcher.findViewById(R.id.list);
View emptyView = viewSwitcher.findViewById(R.id.empty);
list.setEmptyView(emptyView);
View sectionHeading = inflater.inflate(R.layout.heading, list, false);
TextView sectionHeadingTextView = (TextView) sectionHeading.findViewById(R.id.headingText);
sectionHeadingTextView.setText(headerText);
list.addHeaderView(sectionHeading);
list.setAdapter(listAdapter);
list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
listAdapter.getItem(position);
//Do something with it
}
});
}
Alguns métodos do adaptador:
@Override
public int getViewTypeCount() {
return TYPE_COUNT;
}
@Override
public int getItemViewType(int position) {
return (position < items.size()) ? ITEM_NORMAL : ITEM_ADVANCED;
}
@Override
public Product getItem(int position) {
return items.get(position);
}
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
return (position < items.size());
}
Este é o comportamento normal ao adicionar um headerView ?? E como superar os problemas do meu adaptador?
android
listview
listadapter
d1rk
fonte
fonte
Respostas:
Acabei de me deparar com esse problema e a melhor maneira parece usar o em
ListView.getItemAtPosition(position)
vez deListAdapter.getItem(position)
como aListView
versão representa os cabeçalhos, ou seja: -Em vez disso:
fonte
onItemClick
dá a vocêparent
um motivo. Você pode usarparent.getItemAtPosition(position)
AdapterView
também apenas passa para o listAdapter adicionado.return (adapter == null || position < 0) ? null : adapter.getItem(position);
Se você não se importa com o clique no cabeçalho, subtraia o número de visualizações do cabeçalho da posição para obter a posição do adaptador:
fonte
Se você adicionar um cabeçalho a um,
ListView
ele se tornará o primeiro item da lista. Você pode compensar isso, substituindo ogetCount()
para retornar um item menos, mas garantir que você lidar com ogetItem()
,getItemId()
e assim por diante como o cabeçalho seria o item na posição 0.fonte
ListView.getHeaderViewsCount()
Ao implementar
AdapterView.OnItemClickListener
, apenas subtraímos os cabeçalhos da posição.fonte
Não há necessidade de alterar nenhum código. Basta usar o código abaixo.
fonte
Não use o seu adaptador, use o adaptador 'decorado' da getAdapter.
fonte
Uma solução para isso é mapear o id para o índice. Basicamente, make id retornar o índice na lista e o listener de clique faria:
fonte
Olá podemos resolver isso dessa forma primeiro você cria sua view de cabeçalho, depois injeta em sua lista e a última etapa não consegue o setOnClickListener. suas obras para mim. qualquer feedback bem-vindo
fonte
Sem querer adicionar muitas novidades que @Ramesh não adicionou, mas algum contexto extra:
fonte
Use getSelectedItemPosition () Retorne a posição do item atualmente selecionado dentro do conjunto de dados do adaptador. Este método não precisa se preocupar com o tamanho dos cabeçalhos ou rodapés.
fonte
Isso pode ajudar alguém, melhorando a resposta de Farid_z e Philipp, podemos aplicar corretamente o setItemChecked e setTitle com algo assim
fonte