ListView addHeaderView导致位置增加一个?

下面是一个带有ListView的代码片段。 我添加了一个空视图和一个headerView。 添加headerView会导致onItemClick中的位置增加1。

因此,如果没有headerView,第一个列表元素将具有位置0,而headerView中第一个列表元素的位置将是1!

这导致我的适配器错误,例如,当调用getItem()和使用其他方法,请参阅下面。 奇怪的事情:在适配器的getView()方法中,即使添加了headerView,也要求第一个列表元素的位置为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时的正常行为? 以及如何克服在我的适配器的问题?

我只是遇到了这个问题,最好的方式似乎使用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()来减less返回一个项目来弥补这一点,但是确保你处理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 } }); 

不要使用您的适配器,使用getAdapter中的“装饰”适配器。

解决这个问题的方法是将id映射到索引。 基本上使id返回列表中的索引和点击监听器会做:

 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { listAdapter.getItem((int) id); } 

嗨,我们可以通过这种方式解决这个问题,首先你创build你的标题视图,注入后列表和最后一步无法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);