使位置增加一个?

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

因此,如果没有 headerView,第一个 list 元素的位置将为0,而使用 headerView,第一个 list 元素的位置将为1!

这会导致适配器中出现错误,例如在调用 getItem ()和使用其他一些方法时,请参见下文。 奇怪的是: 在适配器的 getView ()方法中,即使添加了 headerView,第一个 list 元素的位置也是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 时的正常行为吗? ? 以及如何克服适配器中的问题?

34422 次浏览

If you add a header to a ListView that becomes the first item in the list. You could compensate for this by overriding the getCount() to return one item less, but ensure you handle the getItem(), getItemId() and so on as the header would be the item in position 0.

I just came across this problem and the best way seems to use the ListView.getItemAtPosition(position) instead of ListAdapter.getItem(position) as the ListView version accounts for the headers, ie:-

Do this instead:

myListView.getItemAtPosition(position)

One solution to this is to map the id to index. Basically make id return the index in the list and the the click listener would do:

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

Do not use your adapter, use 'decorated' adapter from getAdapter.

No need to change any code. Simply use below code.

 list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
parent.getAdapter().getItem(position);
//Do something with it
}
});

If you don't care about the click to the header, subtract the number of header views from the position to get the position for your adapter:

        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);


}
});

Not to add much new that @Ramesh didn't add but some extra context:

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);
}
}
});

When implementing AdapterView.OnItemClickListener we just subtract the headers from the position.

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
position -= mListView.getHeaderViewsCount();
// what ever else follows...
}

Use getSelectedItemPosition() Return the position of the currently selected item within the adapter's data set. This method don't need to worry about the size of headers or footers.

Hi we can resolve this in this way first you create your header view, after inject in your list and the last step unable the setOnClickListener. its works for me. any feedback welcome

ViewGroup headerView = (ViewGroup) getLayoutInflater().inflate(R.layout.your_header, list,false);
list.addHeaderView(headerView);
headerView.setEnabled(false);
headerView.setOnClickListener(null);

This might help somebody, improving on Farid_z and Philipp's answer, we can correctly apply the setItemChecked and setTitle with something like this

        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);