2008-11-02 5 views
101

ListView을 사용하여 표시된 목록에서 한 요소의 픽셀 위치를 알아야합니다. TextView의 중 하나를 가져온 다음 getTop()을 사용해야하는 것처럼 보이지만 ListView의 자식보기를 얻는 방법을 알 수 없습니다.Android : ListView에서 하위보기에 액세스

업데이트 :ViewGroup의 아이들은 1에-1 ListView에 대한 목록의 항목과 일치하지 않습니다. 대신 ViewGroup의 하위 항목은 현재 볼 수있는보기에만 해당합니다. 따라서 getChildAt()ViewGroup 내부의 색인에서 작동하며 목록에서 ListView이 사용하는 위치와 아무런 관련이 없습니다.

답변

210

참조 : Android ListView: get data index of visible item 위 피트의 대답의 일부와 결합, 당신에게 뭔가를 줄 수 :

int wantedPosition = 10; // Whatever position you're looking for 
int firstPosition = listView.getFirstVisiblePosition() - listView.getHeaderViewsCount(); // This is the same as child #0 
int wantedChild = wantedPosition - firstPosition; 
// Say, first visible position is 8, you want position 10, wantedChild will now be 2 
// So that means your view is child #2 in the ViewGroup: 
if (wantedChild < 0 || wantedChild >= listView.getChildCount()) { 
    Log.w(TAG, "Unable to get view for desired position, because it's not being displayed on screen."); 
    return; 
} 
// Could also check if wantedPosition is between listView.getFirstVisiblePosition() and listView.getLastVisiblePosition() instead. 
View wantedView = listView.getChildAt(wantedChild); 

이점은 성능 저하를 취할 수있는, ListView에의 자녀 반복하지 않는 것입니다 .

+10

당신의 명부에있는 전망이있을 때 중대한 응답, 그러나 바르게 작동하지 않는다. 'firstPosition'에 대한 할당은 이것을 수정하기 위해'int firstPosition = listView.getFirstVisiblePosition() - listView.getHeaderViewsCount();'가되어야합니다. – pospi

+0

@pospi : 감사, 좋은 지적! 그 문제를 해결하기 위해 내 대답을 업데이트했습니다. – Joe

+33

의사입니까? 당신이 생명의 은인이기 때문에. 나를 위해 –

5

ListView 클래스에 대한 문서를 빠르게 검색하면 ViewGroup에서 상속 된 getChildCount() 및 getChildAt() 메서드가 나타납니다. 이들을 사용하여 반복 할 수 있습니까? 나는 잘 모르겠지만 시도할만한 가치가있다.

View element = listView.getListAdapter().getView(position, null, null); 

가 그런 다음의 요소를 결정하는 메쏘드 getLeft()와 getTop()를 호출 할 수 있어야한다 :

here

+1

사용 배열 어댑터. 그것은 보통 작동하지만 때때로 off-by-one 오류가 있으며 신뢰할 수 없습니다. 나는 그것을 추천하지 않을 것이다. – Timmmm

+0

감사합니다. Timmmm, 저는 실제로 문서에서 찾았습니다. – Feet

-9

이리스트 뷰에서 요소의 위치를 ​​알고 가정을 찾을 수 화면 위치.

+42

'getView()'는 목록을 채울 때 ListView에 의해 내부적으로 호출됩니다. 'convertView'에 대해'getView()'를 호출하면 어댑터가 어댑터의 레이아웃 리소스에서 새 뷰를 부 풀리게되므로 목록의 해당 위치에서 뷰를 가져올 수 없습니다. 보기가 이미 표시됨). – Joe

+2

우수 포인트! – jasonhudgins

+1

짝수 위치는 어댑터의 데이터 소스 위치가 아닌 시각적 화면의 위치가됩니다. – Vikas

15

이 코드는 쉽게 사용할 수 :

기본적으로
View rowView = listView.getChildAt(viewIndex);//The item number in the List View 
    if(rowView != null) 
     { 
      // Your code here 
     } 
+0

잘 작동합니다. 왜 당신이 downvote ... upvote있어 모르겠어요! – Mark

+9

이 항상 작동하지 않습니다. getChildAt는 데이터의 맨 위가 아닌 첫 번째 보이는 행에서부터 계산됩니다. – SteelBytes

+13

ViewID 인수가 혼동을줍니다. 그것은 인덱스 (또는 위치)입니다. 뷰 ID는 aapt 도구로 생성 된 완전히 임의의 정수입니다. –

5
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { 

    @Override 
public void onItemClick(AdapterView<?> parent, final View view, int position, long id) 
{  
    View v; 
    int count = parent.getChildCount(); 
    v =parent.getChildAt(position); 
    parent.requestChildFocus(v, view); v.setBackground(res.getDrawable(R.drawable.transparent_button)); 
      for (int i=0; i<count; i++) 
      { 
       if (i!= position) 
       { 
        v = parent.getChildAt(i);t v.setBackground(res.getDrawable(R.drawable.not_clicked)); 

       } 
      } 
     } 
    }); 

, 두 드로어 블을 생성 - 원하는 색상 투명 하나, 또 다른합니다. 클릭 한 위치 (정의 된 int 위치)에서 포커스를 요청하고 해당 행의 색상을 변경합니다. 그런 다음 부모 listview을 살펴보고 그에 따라 다른 모든 행을 변경하십시오. 사용자가 listview 번을 여러 번 클릭 할 때 차지합니다. 이것은 listview의 각 행에 대한 사용자 정의 레이아웃으로 수행됩니다. (아주 간단하게하는 textview 그냥 새로운 레이아웃 파일 - 포커스 또는 클릭 설정하지 마십시오!) 어떤 사용자 정의 어댑터가 필요하지 않습니다 - 나는 선택을하는 경우,이 시도했습니다

+0

getChildAt는 현재 스크롤 된 항목을 기준으로합니다. 목록을 조금만 스크롤하면 작업이 중단됩니다. – nurettin

4
int position = 0; 
listview.setItemChecked(position, true); 
View wantedView = adapter.getView(position, null, listview); 
+1

정교한 조금 – innoSPG

+0

신의 축복이 젠체, 내 목숨을 구해줘. – Euphor08