ArrayAdapter의 getViewTypeCount 및 getItemViewType 메소드


159

누군가 평범한 단어로 사용법 getViewTypeCount()getItemViewType()방법을 설명 할 수 있습니까 ArrayAdapter?

답변:


308

행 마다 다른 유형 의보기를 원하는 경우를 처리합니다 . 예를 들어, 연락처 애플리케이션에서 행에도 왼쪽에 그림이 있고 홀수 행에 오른쪽에 그림이있을 수 있습니다. 이 경우 다음을 사용합니다.

@Override
public int getViewTypeCount() {
    return 2;
}

@Override
public int getItemViewType(int position) {
    return position % 2;
}

프레임 워크는 뷰 유형을 사용 하여 메소드 에서 처리 할 뷰를 결정 합니다.convertViewgetView . 즉, 위의 예에서 짝수 행은 재사용 할 수 있도록 왼쪽에 그림이있는 재활용 뷰만 가져오고 홀수 행은 오른쪽에 그림이있는 뷰만 가져옵니다.

목록의 모든 행이 동일한 레이아웃을 갖는 경우 뷰 유형에 대해 걱정할 필요가 없습니다. 실제로 BaseAdapter.java 는 모든 어댑터에 대한 기본 동작을 제공합니다.

public int getItemViewType(int position) {
    return 0;
}

public int getViewTypeCount() {
    return 1;
}

이것은 실제로 모든 행에 대해 동일한 뷰 유형을 제공합니다.

편집 -일반적인 흐름을 설명합니다.

  1. AdapterView어댑터를 사용하여 데이터를 바인딩합니다 .
  2. AdapterView시도는 사용자가 볼 수있는 항목을 표시합니다.
  3. 프레임 워크는 표시 getItemViewType할 행인 row를 호출 n합니다.
  4. 프레임 워크는 재활용 된 뷰 풀에서 행 n유형 의 뷰를 확인 합니다. 뷰가 아직 재활용되지 않았기 때문에 아무것도 찾지 못했습니다.
  5. getViewrow를 호출합니다 n.
  6. 사용할 뷰 유형을 결정 getItemViewType하기 위해 행 n을 호출 합니다.
  7. 필요한 뷰 유형에 따라 if / switch 문을 사용하여 다른 xml 파일을 부 풀릴 수 있습니다.
  8. 뷰를 정보로 채 웁니다.
  9. 뷰를 종료 getView하고 종료 하면 행의 뷰가 사용자에게 표시됩니다.

이제 화면을 스크롤하여보기를 재활용하면 프레임 워크에서 관리하는 재활용보기 풀로 이동합니다. 이들은 본질적으로 뷰 유형별로 구성되므로 메소드의 convertView매개 변수에서 올바른 유형의 뷰가 제공됩니다 getView.

  1. 프레임 워크는 다시 getItemViewType표시하려는 행을 호출 합니다.
  2. 이번에는 해당 유형의 재활용 풀에 대한보기가 있습니다.
  3. 재활용 된 뷰는 메소드 의 convertView매개 변수 로 전달됩니다 getView.
  4. 재활용 된 뷰를 새로운 정보로 채우고 반환합니다.

1
@Matthew, 답변 주셔서 감사합니다. 이러한 메소드가 어떻게 호출되는지 흐름을 설명 할 수 있습니까? 또한 이것이 실제로 res / layout의 데이터와 어떻게 관련되어 있는지 이해하지 못합니다.
Eugene

이러한 메소드가 호출되는 시점에 대한 명시적인 계약은 없습니다. res / layout은 객체를 위한 장소입니다 . 이것은 어댑터 입니다. getView 메소드에서 항목 유형을 확인하고 그에 따라 적절한보기를 res / layout으로 부풀려 야합니다.
매튜 윌리스

1
getItemViewType에서 직접 반환합니다.
매튜 윌리스

당신의 getView에서 수동으로 연결을 수행합니다 (유형 == 0) {/ * R.layout.row_icon_on_left을 팽창 경우 /} 다른 {/ R.layout.row_icon_on_right * / 팽창}
매튜 윌리스

75
조심해! getItemViewType ()은 0과 getViewTypeCount ()-1 사이의 정수를 반환해야합니다.
PacificSky

12

우리가보기의 다른 유형 표시해야하는 경우 사용 후의 좋은 목록을-보기 getViewTypeCount()getItemViewType()보기를 전환하는 대신 어댑터 View.GONEView.VISIBLE매우 비싼 작업 내부 될 수 있습니다 getView()목록 스크롤에 영향을 미칠 것입니다.

어댑터 사용 getViewTypeCount()getItemViewType()어댑터에 대해서는이 항목을 확인하십시오 .

링크 : get-use-of-getviewtypecount


getItemViewType ()에서 IGNORE_ITEM_VIEW_TYPE을 반환하면 getUI (int position, View view, ViewGroup viewGroup)에서 항상 모든 UI 구성 요소를 초기화하도록 'view'를 null로 전달합니다. 홀더 패턴의 경우 기존 UI 뷰를 재사용하고 위치를 기준으로 뷰를 View.GONE 또는 View.VISIBLE로 간단히 전환 할 수있는 성능 저하가 아닙니다.
Namrata Bagerwal

11

조심해 !!!!
나는 구현 문제에 직면했다ListView어제 스크롤 한 직후에 행에 대한 두 가지 유형의보기가 뒤죽박죽되었습니다. 이 스레드 내에서 가장 많이 투표 된 답변은 일반적인 설명을 제공하지만 위에서 언급 한 위의 UI 버그를 막기 위해 가장 중요한 정보는 강조하지 않았습니다.

여기 내 설명입니다
모두 getViewTypeCount()getItemViewType()사용중인 BaseAdaptergetView방법은 재활용 및 반환, 인출해야 뷰의 종류를 확인합니다. (스레드 내의 맨 위 답변에 설명되어 있음). 그러나 Android API Doc에 따라이 두 가지 방법을 직관적으로 구현하지 않으면 위에서 언급 한 문제가 발생할 수 있습니다.

구현에 대한 요약 지침 :
여러 행 유형에 Views대해 ListView행을 구현하려면 기본적으로 구현해야 getItemViewType()하며 getViewTypeCount()메소드가 있습니다. 그리고 getItemViewType()문서는 우리에게 다음과 같은 메모를 제공합니다.

참고 : 정수의 범위에 있어야 0getViewTypeCount() - 1. IGNORE_ITEM_VIEW_TYPE반환 할 수도 있습니다.

따라서 getItemViewType()0에서 시작하여 마지막 유형으로 (유형 수-1)로 뷰 유형의 값을 반환해야합니다. 예를 들어, 세 가지 유형의보기 만 있다고 가정 해 봅시다. 따라서 뷰의 데이터 객체에 따라 0 기반 배열 인덱스와 같이 메소드 에서 0 또는 1 또는 2 만 반환 할 수 getItemViewType()있습니다. 세 가지 유형의 뷰가 사용되므로 getViewTypeCount()메서드는 3을 반환해야합니다.

어쨌든이 방법에 대해 1, 2, 3 또는 111, 222, 333과 같은 다른 정수 값을 반환하면 Android API Doc을 따르지 않고 위의 UI 버그가 발생할 수 있습니다.

실마리를 얻지 못했거나 여전히 해결할 수없고 추가 정보가 필요한 경우이 StackOverflow Q & A 스레드 내에서 자세한 답변을 읽으십시오 .

힌트를 찾을 수있는 자세한 정보 는 Android 개발자 문서 를 참조하십시오.

이 답변이 많은 시간을 절약하기 위해 거기에있는 누군가에게 도움이되기를 바랍니다.

건배!!!


1
IGNORE_ITEM_VIEW_TYPE내 ListView 중 하나에 버그가 있다고 언급 해 주셔서 감사합니다 . ArrayAdapter를 사용하여 1 개의 이미지와 2 개의 텍스트보기로 구성된보기를 삽입했습니다. 뷰 유형이 하나뿐이었습니다. getItemViewType 메서드를 재정의하지 않거나 위치 또는 하드 코딩 된 정수를 반환하여 재정의하려고했습니다. 모든 경우에, 나는 스크롤 할 때 이상한 행동으로 목록에 중복이 발생했습니다 (중복 변경). IGNORE_ITEM_VIEW_TYPE이 방법 으로 돌아와서 문제가 해결되었습니다. 감사.
Alex

@Alex는 그것이 당신에게 도움이되어 기뻤습니다! :-)
Randika Vishman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.