ListView addHeaderView вызывает увеличение позиции на единицу?
Ниже приведен фрагмент кода с ListView. Я добавил emptyView и headerView. Добавление headerView приводит к увеличению позиции в onItemClick на единицу.
таким образом, без headerView первый элемент списка будет иметь позицию 0, с headerView позиция первого элемента списка будет 1!
это вызывает ошибки в моем адаптере, например, при вызове getItem () и использовании некоторых других методов, см. ниже. Странная вещь: в методе getView() адаптер первый элемент списка запрашивается с позиции 0, даже если добавлен headerView!!
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?? И как преодолеть проблемы в моем адаптере?
11 ответов:
Я только что столкнулся с этой проблемой, и лучший способ, кажется, использовать
ListView.getItemAtPosition(position)
вместоListAdapter.getItem(position)
какListView
версия учитывает заголовки, т. е.: -вместо этого:
myListView.getItemAtPosition(position)
Если вы не заботитесь о щелчке по заголовку, вычитайте количество просмотров заголовка из позиции, чтобы получить позицию для вашего адаптера:
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); } });
если вы добавляете заголовок к
ListView
это становится первым пунктом в списке. Вы можете компенсировать это, переопределивgetCount()
вернуться на один элемент меньше, но убедитесь, что вы обрабатыватьgetItem()
,getItemId()
и так далее, поскольку заголовок будет элементом в позиции 0.
при осуществлении
AdapterView.OnItemClickListener
мы просто вычитаем заголовки из позиции.@Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { position -= mListView.getHeaderViewsCount(); // what ever else follows... }
нет необходимости менять какой-либо код. Просто используйте ниже код.
list.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { parent.getAdapter().getItem(position); //Do something with it } });
одним из решений этого является сопоставление идентификатора с индексом. В основном make id возвращает индекс в списке, и прослушиватель щелчка будет делать:
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { listAdapter.getItem((int) id); }
Привет, мы можем решить это таким образом сначала вы создаете свой вид заголовка, после ввода в свой список и последнего шага не удается setOnClickListener. это работает для меня. любая обратная связь приветствуется
ViewGroup headerView = (ViewGroup) getLayoutInflater().inflate(R.layout.your_header, list,false); list.addHeaderView(headerView); headerView.setEnabled(false); headerView.setOnClickListener(null);
не добавить много нового, что @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); } } });
с помощью getSelectedItemPosition () возвращает позицию текущего выбранного элемента в наборе данных адаптера. Этот метод не нужно беспокоиться о размере верхних или нижних колонтитулов.
Это может помочь кому-то, улучшая ответ 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);