Android ListView 의 OnItemClickListener 상세 설명

저 희 는 ListView 를 사용 할 때 보통 ListView 에 응답 이벤트 android.widget.adapterView 를 추가 합 니 다.OnitemClickListener.본 고 는 주로 Onitem ClickListener 의 position 와 id 매개 변수 에 대해 상세 하 게 설명 하 는 데 있 습 니 다.저 는 어떤 사람들 이 이 위 에서 시행 착 오 를 걸 었 다 고 믿 습 니 다.
일단 공식 문 서 를 보 겠 습 니 다.
position The position of the view in the adapter.
id The row id of the item that was clicked.
이 두 줄 의 글 자 는 position 와 id 의 차 이 를 명확 하 게 설명 하지 않 았 다.그리고 Adapter 의 getView 방법 도 있 습 니 다.
public abstract View getView (int position, View convertView, ViewGroup parent)
여기 도 포지션 이 하나 있어 요.
ListView 를 처음 접 하 는 친구 들 은 보통 Array Adapter 를 직접 계승 하고(예 를 들 어 나)OnitemClick 의 position 와 getView 의 position 가 같다 고 생각 합 니 다.그래서 우 리 는 getItem(position)으로 해당 하 는 데 이 터 를 얻 습 니 다.
그럼 이 코드 가 틀 렸 나 요?만약 잘못 이 있다 면,어떤 상황 에서 실 수 를 할 수 있 습 니까?
첫 번 째 문제 의 답 은 우리 가 ListView 에 header View 나 footer View 를 추가 한 후에 이 코드 는 반드시 우리 가 원 하 는 것 이 아니 라 는 것 이다.
문제 가 생 긴 이 유 는 ListView 에 header View 나 footer View 를 추가 한 후에 ListView 가 setAdapter 에서 뭔 가 를 했 기 때 문 입 니 다.이 로 인해 Adapter 와 Onitem ClickListener 의 position 의미 가 달 라 졌 습 니 다.
ListView 에서 setAdapter 의 실현 을 살 펴 볼 수 있 습 니 다.

public void setAdapter(ListAdapter adapter) { 
if (mAdapter != null && mDataSetObserver != null) { 
mAdapter.unregisterDataSetObserver(mDataSetObserver); 
} 
resetList(); 
mRecycler.clear(); 
if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) { 
mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter); 
} else { 
mAdapter = adapter; 
} 
이 ListView 에 header View 나 footer View 가 존재 한다 면 우리 가 들 어 오 는 adapter 밖 에 Header View ListAdapter 를 패키지 합 니 다.이것 은 header View 와 footer View 를 자동 으로 처리 하 는 adapter 입 니 다.ListView 에 서 는 header View,footer View 를 구분 하지 않 습 니 다.ListView 는 하나의 View 만 관리 하 는 배열 의 UI(ViewGroup)로 이해 할 수 있 으 며,header View 와 footer View 는 모두 HeaderView ListAdapter 에 의뢰 하여 처리 합 니 다.(API 문서 에서 addFooter View 와 addHeaderView 가 setAdapter 함수 전에 호출 되 어야 하 는 이 유 를 알 수 있 습 니 다.나중에 호출 하면 HeaderView ListAdapter 가 생 성 되 지 않 아 header View 와 footer View 가 표시 되 지 않 습 니 다).
시작 문제 로 돌아 가면 position 와 id 는 어떤 차이 가 있 습 니까?이 를 위해 포지션 과 id 가 어떻게 들 어 왔 는 지 찾 아 보 겠 습 니 다.
OnitemClickListener 는 android.widget.adapterView 의 Public boolean permitemClick(View view,int position,long id)함수 에서 호출 되 었 습 니 다.
permitemClick 은 android.widget.AbsListView.PerformClick.run()에서 호출 됩 니 다.

private class PerformClick extends WindowRunnnable implements Runnable { 
int mClickMotionPosition; 
public void run() { 
// The data has changed since we posted this action in the event queue, 
// bail out before bad things happen 
if (mDataChanged) return; 
final ListAdapter adapter = mAdapter; 
final int motionPosition = mClickMotionPosition; 
if (adapter != null && mItemCount > 0 && 
motionPosition != INVALID_<strong>POSITION</strong> && 
motionPosition < adapter.getCount() && sameWindow()) { 
final View view = getChildAt(motionPosition - mFirstPosition); 
// If there is no view, something bad happened (the view scrolled off the 
// screen, etc.) and we should cancel the click 
if (view != null) { 
performItemClick(view, motionPosition, adapter.getItemId(motionPosition)); 
} 
} 
} 
} 
포지션 은 사실상 ListView 에서 클릭 된 view 의 위 치 를 볼 수 있 습 니 다.ListView 에 서 는 header View 와 footViewer 를 처리 하지 않 습 니 다.따라서 이 위 치 는 클릭 한 view 가 배열[모든 header View,사용자 가 추가 한 view,모든 footer View]에 있 는 위치 일 것 입 니 다.id 는 adapter.getItemId(position)에서 왔 습 니 다.
Array Adapter 의 getItemId 함수 에 대해 실현 은 return position 입 니 다.id 와 position 는 일치 합 니 다.
하지만 HeaderView ListAdapter 에 대해 서 는

public long getItemId(int <strong>position</strong>) { 
int numHeaders = getHeadersCount(); 
if (mAdapter != null && <strong>position</strong> >= numHeaders) { 
int adjPosition = <strong>position</strong> - numHeaders; 
int adapterCount = mAdapter.getCount(); 
if (adjPosition < adapterCount) { 
return mAdapter.getItemId(adjPosition); 
} 
} 
return -1; 
} 
논 리 를 실현 하 는 것 은 position 이 header View 나 footer View 를 가리 키 면-1 로 돌아 가 고 그렇지 않 으 면 사용자 view 배열 의 위치 로 돌아 가 는 것 입 니 다.
그 러 니까
id=position-header View 의 개수(id따라서 OnitemClickListener 의 정확 한 실현 은 다음 과 같다.

void onItemClick(AdapterViewparent, View view, int <strong>position</strong>, long id){ 
if(id == -1) { 
//     headerView  <strong>footerView</strong> 
return; 
} 
int realPosition=(int)id; 
T item=getItem(realPosition); 
//      
}
관련 읽 기:
Android 에서 ListView setOnItemClickListener 클릭 이 잘못된 원인 분석
위 에서 말 한 것 은 편집장 님 께 서 소개 해 주신 안 드 로 이 드 리 스 트 뷰 의 온 아 이 템 클릭 리 스 터 입 니 다.여러분 께 도움 이 되 셨 으 면 좋 겠 습 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.편집장 님 께 서 바로 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기