program tip

ListView addHeaderView로 인해 위치가 1 씩 증가합니까?

radiobox 2020. 8. 28. 07:17
반응형

ListView addHeaderView로 인해 위치가 1 씩 증가합니까?


아래는 ListView가있는 코드 조각입니다. emptyView와 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)은 AS 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()항목 하나를 적게 반환 하여이를 보완 할 수 있지만 헤더가 위치 0에있는 항목이므로 getItem(), getItemId()을 처리해야합니다 .


구현할 때 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의 '장식 된'어댑터를 사용하십시오.


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

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

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

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.


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

참고URL : https://stackoverflow.com/questions/11106397/listview-addheaderview-causes-position-to-increase-by-one

반응형