Vous trouverez ci-dessous un extrait de code avec un ListView. J'ai ajouté un emptyView et un headerView. L'ajout de headerView entraîne une augmentation de la position dans onItemClick.
Donc, sans headerView, le premier élément de la liste aurait la position 0, avec l'en-têteView la position du premier élément de la liste serait 1!
Cela provoque des erreurs dans mon adaptateur, par exemple lors de l'appel de getItem () et de l'utilisation d'autres méthodes, voir ci-dessous. Chose étrange: dans la méthode getView () de l'adaptateur, le premier élément de liste est demandé avec la position 0 même si l'en-têteView est ajouté !!
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
}
});
}
Quelques méthodes d'adaptateur:
@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());
}
Est-ce le comportement normal lors de l'ajout d'un headerView? Et comment surmonter les problèmes de mon adaptateur?
Réponses:
Je viens de tomber sur ce problème et la meilleure façon semble d'utiliser le
ListView.getItemAtPosition(position)
au lieu deListAdapter.getItem(position)
car laListView
version tient compte des en-têtes, c'est-à-dire: -Faites ceci à la place:
la source
onItemClick
vous donneparent
une raison. Vous pouvez utiliserparent.getItemAtPosition(position)
AdapterView
passe également simplement au listAdapter ajouté.return (adapter == null || position < 0) ? null : adapter.getItem(position);
Si vous ne vous souciez pas du clic sur l'en-tête, soustrayez le nombre de vues d'en-tête de la position pour obtenir la position de votre adaptateur:
la source
Si vous ajoutez un en-tête à un,
ListView
cela devient le premier élément de la liste. Vous pouvez compenser cela en remplaçant legetCount()
pour renvoyer un élément de moins, mais assurez-vous de gérer legetItem()
,getItemId()
et ainsi de suite car l'en-tête serait l'élément en position 0.la source
ListView.getHeaderViewsCount()
Lors de la mise en œuvre,
AdapterView.OnItemClickListener
nous soustrayons simplement les en-têtes de la position.la source
Pas besoin de changer de code. Utilisez simplement le code ci-dessous.
la source
N'utilisez pas votre adaptateur, utilisez l'adaptateur «décoré» de getAdapter.
la source
Une solution à cela consiste à mapper l'id à l'index. Fondamentalement, faites que id renvoie l'index dans la liste et l'écouteur de clic ferait:
la source
Salut, nous pouvons résoudre cela de cette manière, vous créez d'abord votre vue d'en-tête, après l'injection dans votre liste et la dernière étape impossible le setOnClickListener. ses travaux pour moi. toute rétroaction bienvenue
la source
Pas pour ajouter beaucoup de nouveautés que @Ramesh n'a pas ajoutées, mais un contexte supplémentaire:
la source
Use getSelectedItemPosition () Renvoie la position de l'élément actuellement sélectionné dans l'ensemble de données de l'adaptateur. Cette méthode n'a pas besoin de se soucier de la taille des en-têtes ou des pieds de page.
la source
Cela pourrait aider quelqu'un, en améliorant la réponse de Farid_z et Philipp, nous pouvons correctement appliquer setItemChecked et setTitle avec quelque chose comme ça
la source