ListView addHeaderView приводит к увеличению позиции на единицу?
Ниже приведен фрагмент кода с помощью ListView. Я добавил emptyView и headerView. Добавление headerView приводит к увеличению позиции в onItemClick на единицу.
Таким образом, без элемента headerView первый элемент списка будет иметь позицию 0, а заголовочный элемент позиции первого элемента списка будет равен 1!
Это вызывает ошибки в моем адаптере, например. при вызове getItem() и использовании некоторых других методов, см. ниже.
Странная вещь: в методе getView() адаптера первый элемент списка запрашивается с позицией 0, даже если добавлен заголовок!!
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
}
});
}
Некоторые методы адаптера:
@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());
}
Это обычное поведение при добавлении headerView? И как преодолеть проблемы в моем адаптере?
Ответы
Ответ 1
Я просто столкнулся с этой проблемой, и лучший способ, по-видимому, использует ListView.getItemAtPosition(position)
вместо ListAdapter.getItem(position)
, поскольку версия версии ListView
учитывает заголовки, то есть: -
Сделайте это вместо:
myListView.getItemAtPosition(position)
Ответ 2
Если вам не нужен щелчок по заголовку, вычтите количество просмотров заголовков из позиции, чтобы получить позицию для вашего адаптера:
listView.addHeaderView(inflater.inflate(
R.layout.my_hdr_layout, null), null, false);
listView.setAdapter(m_adapter);
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
position -= listView.getHeaderViewsCount();
final MyObject object = m_adapter.getItem(position);
}
});
Ответ 3
Если вы добавите заголовок в ListView
, который станет первым элементом в списке. Вы можете компенсировать это, переопределив getCount()
, чтобы вернуть один элемент меньше, но убедитесь, что вы обрабатываете getItem()
, getItemId()
и т.д., Поскольку заголовок будет элементом в позиции 0.
Ответ 4
При реализации AdapterView.OnItemClickListener
мы просто вычитаем заголовки из позиции.
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
position -= mListView.getHeaderViewsCount();
// what ever else follows...
}
Ответ 5
Не нужно менять код. Просто используйте приведенный ниже код.
list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
parent.getAdapter().getItem(position);
//Do something with it
}
});
Ответ 6
Не используйте адаптер, используйте "украшенный" адаптер от getAdapter.
Ответ 7
Одним из решений этого является сопоставление идентификатора с индексом. В основном make id возвращает индекс в списке, и получатель кликов будет делать:
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
listAdapter.getItem((int) id);
}
Ответ 8
Привет, мы можем разрешить это таким образом
сначала вы создаете свой заголовок, после ввода в свой список и последнего шага, неспособного setOnClickListener. его работы для меня. любая обратная связь приветствуется
ViewGroup headerView = (ViewGroup) getLayoutInflater().inflate(R.layout.your_header, list,false);
list.addHeaderView(headerView);
headerView.setEnabled(false);
headerView.setOnClickListener(null);
Ответ 9
Не добавлять много нового, что @Ramesh не добавлял, а добавлял дополнительный контекст:
personList.setOnItemClickListener(new OnItemClickListener() {
@SuppressWarnings("unchecked")
public void onItemClick( AdapterView<?> parent, View view, int position, long duration) {
Map<String, Object> person = (Map<String, Object>) parent.getAdapter().getItem(position);
if (person != null){
// If the header was clicked on a null is returned
OnPersonUiChangeListener listener = (OnPersonUiChangeListener) getActivity();
listener.onSelectedPersonChanged(person);
}
}
});
Ответ 10
Использовать getSelectedItemPosition() Возвратить позицию выбранного в данный момент элемента в наборе данных адаптера.
Этот метод не нужно беспокоиться о размере верхних или нижних колонтитулов.
Ответ 11
Это может помочь кому-то, улучшив ответы Farid_z и Philipp, мы можем правильно применить setItemChecked и setTitle с чем-то вроде этого
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
position += 1;
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
position -= 1;
setTitle(mNavigationDrawerItemTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);