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. フレームワークはgetItemViewTypen表示しようとしている行であるrowを呼び出します。
  4. フレームワークは、行nのタイプのビューについてリサイクルされたビュープールをチェックします。ビューがまだリサイクルされていないため、何も見つかりません。
  5. getView行に対して呼び出されnます。
  6. getItemViewTypenを呼び出して、使用するビューのタイプを決定します。
  7. if / switchステートメントを使用して、必要なビュータイプに応じて異なるxmlファイルを拡張します。
  8. ビューに情報を入力します。
  9. ビューを終了してを終了getViewすると、行のビューがユーザーに表示されます。

これで、画面からスクロールしてビューがリサイクルされると、フレームワークによって管理されるリサイクルされたビュープールに入ります。これらは基本的にビュータイプごとに編成されているためconvertViewgetViewメソッドのパラメーターで正しいタイプのビューが提供されます。

  1. フレームワークは再びgetItemViewType表示したい行を呼び出します。
  2. 今回は、適切なタイプのリサイクルされたプールにビューがあります。
  3. リサイクルされたビューは、convertViewパラメーターとしてgetViewメソッドに渡されます。
  4. リサイクルされたビューに新しい情報を入力し、それを返します。

1
@マシュー、あなたの答えをありがとう。これらのメソッドがどのように呼び出されるかのフローを説明できますか。また、これが実際にres / layoutのデータとどのように関連付けられているのかもわかりません。
ユージーン

これらのメソッドがいつ呼び出されるかについて明示的なコントラクトはありません。res / layoutはビューオブジェクトの場所です。これがアダプターです。getViewメソッドで項目タイプを確認し、それに応じてres / layoutから適切なビューを膨らませる必要があります。
マシューウィリス

1
getItemViewTypeで自分で返します。
マシューウィリス

getViewで手動で関連付けを行います。if(type == 0){/ * inflate R.layout.row_icon_on_left /} else {/ inflate R.layout.row_icon_on_right * /}
Matthew Willis

75
注意してください!getItemViewType()は0からgetViewTypeCount()-1までの整数を返す必要があります
。– PacificSky

12

使用に私たちは、リストビュー内のビューの異なる種類を表示する必要がある場合は、その良いgetViewTypeCount()getItemViewType()アダプタ内の代わりにビューを切り替えるのView.GONEView.VISIBLE内側に非常に高価な作業になることがgetView()リストのスクロールに影響を与えるであろう。

アダプターの使用方法についてはgetViewTypeCount()、こちらをご確認くださいgetItemViewType()

リンク:the-use-of-getviewtypecount


getItemViewType()でIGNORE_ITEM_VIEW_TYPEを返すと、getView(int position、View view、ViewGroup viewGroup)で常に「view」がnullとして渡され、すべてのUIコンポーネントが強制的に初期化されます。ホルダーパターンの場合に既存のUIビューを再利用でき、位置に基づいてビューをView.GONEまたはView.VISIBLEに切り替えるだけで、パフォーマンスが悪くなるわけではありません。
Namrata Bagerwal

11

Outttt !!!を見る
私はListView昨日実装する問題に直面しなければなりませんでした、そしてそれは私がそれをスクロールした直後に行のための乱雑になった2つのタイプのビューです。このスレッド内で投票数の多い回答は良い一般的な説明を提供しますが、私が言及した上記のUIバグを阻止するための最も重要な情報は強調されていません。

ここに私の説明は次のとおりです。
両方getViewTypeCount()getItemViewType()で使用されているBaseAdaptergetViewそれはリサイクルされて返さ、フェッチする必要があるビューの種類を見つけるための方法。(スレッド内の一番上の答えで説明されているように)。しかし、Android API Docに従ってこれらの2つのメソッドを直感的に実装しないと、前述の問題が発生する可能性があります。

実装の要約されたガイドライン:
複数のタイプのViewsfor ListViewの行を実装するには、基本的に実装する必要のある行getItemViewType()getViewTypeCount()メソッドです。そして、getItemViewType()ドキュメントは次のように私たちにメモを与えます:

注:整数は0からの範囲でなければなりませんgetViewTypeCount() - 1IGNORE_ITEM_VIEW_TYPE返品も可能です。

したがってgetItemViewType()、ビュータイプの値を0から最後のタイプまで(タイプの数-1)として返す必要があります。たとえば、ビューが3種類しかないとしましょう。したがって、ビューのデータオブジェクトによっては、0から始まる配列インデックスのように、メソッドから0または1または2しか返せませんでしたgetItemViewType()。また、使用するビューには3つのタイプがあるため、getViewTypeCount()メソッドは3を返す必要があります。

いずれの場合も、このメソッドに対して1、2、3、または111、222、333などの他の整数値を返すと、Android APIのドキュメントに従っていないため、上記のUIバグが発生する可能性があります。

手がかりがつかない、または解決できないためさらに情報が必要な場合は、このStackOverflow Q&Aスレッド内の詳細な回答を読んでください。

手がかりが直接見つかるかもしれない詳細については、Android開発者ドキュメントをお読みください。

この答えが誰かを助けて、たくさんの時間を節約してくれることを願っています!!!

乾杯!!!


1
IGNORE_ITEM_VIEW_TYPEリストビューの1つにバグがあったことに言及していただきありがとうございます。ArrayAdapterを使用して、1つのイメージと2つのテキストビューで構成されるビューを挿入しました。ビュータイプは1つだけでした。メソッドgetItemViewTypeをオーバーライドしないようにするか、位置またはハードコードされた整数を返すことによってオーバーライドしようとしました。すべてのケースで、リストの重複が発生しました。スクロールすると奇妙な動作になります(変更が重複します)。IGNORE_ITEM_VIEW_TYPEメソッドに戻ると問題が修正されました。ありがとう。
アレックス

@アレックスはあなたのために役に立ててうれしいです!:-)
Randika Vishman
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.