独自のカスタムアダプターを作成する場合、getView()メソッドはどのように機能しますか?


101

私の質問は:

  1. LayoutInflaterの正確な機能は何ですか?
  2. 私が読んだすべての記事で、convertviewがnullであるかどうかが最初に確認されるのはなぜですか?nullの場合はどういう意味ですか、そうでない場合はどういう意味ですか?
  3. このメソッドが受け入れる親パラメーターは何ですか?

回答:


115

1:LayoutInflaterは、レイアウトXMLファイルを受け取り、そのコンテンツからさまざまなViewオブジェクトを作成します。

2:アダプタはビューを再利用するように構築されています。ビューがスクロールされて表示されなくなると、表示される新しいビューの1つに使用できます。この再利用されたビューはconvertViewです。これがnullの場合は、リサイクルされたビューがないため、新しいビューを作成する必要があります。それ以外の場合は、ビューを使用して新しいビューを作成しないようにする必要があります。

3:parentは提供されているので、適切なレイアウトパラメータのためにビューを膨らませることができます。

これらすべてを一緒に使用して、リストに表示されるビュー(またはアダプターを使用する他のビュー)を効果的に作成できます。

public View getView(int position, @Nullable View convertView, ViewGroup parent){
    if (convertView == null) {
        //We must create a View:
        convertView = inflater.inflate(R.layout.my_list_item, parent, false);
    }
    //Here we can do changes to the convertView, such as set a text on a TextView 
    //or an image on an ImageView.
    return convertView;
}

お知らせの使用LayoutInflater、それはparentそれのための引数として使用することができ、そしてどのようにconvertView再利用されます。


5
Convertview == nullは、すべてのitensが同じレイアウトに従う場合に便利です。たとえば、ラジオやチェックされたボタンをチェックし、各アイテムに基づいてレイアウトを変更する必要がある場合、再インフレートする必要があります。そうしないと、キャッシュされたビューを取得します。
sagits 2015

再度膨らませる必要はありません。getviewにスイッチまたはif-elseラダーを記述し、必要に応じてビューをインフレートするだけで、public int getItemViewType(int position)およびpublic int getViewTypeCount()をオーバーライドします。@sagits
Prashanth Debbadwar

ステートメントは通常は機能しますが、ラジオボタン、編集テキスト、およびキャッシュビューを使用して問題が発生したこの種のものを使用する場合、スタックオーバーフローでこの問題に関するいくつかの質問があります。
sagits

71

getView()アダプタでの方法は、以下の項目のビューを生成するためのものですListViewGallery...

  1. LayoutInflater(通常、ルートオブジェクト、あなたはレイアウトXMLで定義するViewオブジェクトを取得するために使用されるLinearLayoutFrameLayoutまたはRelativeLayout

  2. convertViewリサイクル用です。一度に10アイテムしか表示できないリストビューがあり、現在はアイテム1->アイテム10を表示しているとします。1つのアイテムを下にスクロールすると、アイテム1は画面外になり、アイテム11が表示されます。 。アイテム11のビューを生成するために、getView()メソッドが呼び出され、 convertViewここにアイテム1のビューがあります(これはもう必要ありません)。したがって、代わりにアイテム11(コストが高い)の新しいViewオブジェクトを作成し、なぜ再利用しconvertViewないのですか?=> convertViewnullかどうかを確認します。nullの場合は新しいビューを作成し、それ以外の場合はを再利用しますconvertView

  3. parentViewgetView()生成するアイテムのビューを含むリストビューまたはギャラリーです。

:このメソッドを直接呼び出すのではなく、アイテムのビューの生成方法を親ビューに通知するために実装する必要があります。


2
parentViewの優れた説明、これよりも優れた説明を見つけることはできません、+ 1
Ahmed Adel Ismail

すごい説明!
gabi

素晴らしい説明+1
tpk

8

リストビューについては、このビデオをご覧ください。それは昨年のGoogle IOからのものであり、私の頭の中でのリストビューのウォークスルーとしては最高です。

http://www.youtube.com/watch?v=wDBM6wVEO70

  1. レイアウト(res / layout /フォルダーのxmlファイル)を、LinearLayoutやその他のビューなどのJavaオブジェクトに拡張します。

  2. ビデオを見て、変換ビューの使い方を最新のものにしてください。基本的には、再利用されるのを待って再利用されるビューであり、新しいオブジェクトの作成やリストのスクロール速度の低下を防ぎます。

  3. アダプターからリストビューを参照できます。


5

LayoutInflaterの正確な機能は何ですか?

XMLを使用して設計する場合、すべてのUI要素は単なるタグとパラメーターです。これらのUI要素(TextViewやLinearLayoutなど)を使用する前に、これらのxml要素に対応する実際のオブジェクトを作成する必要があります。それがインフレーターの目的です。インフレーターは、これらのタグとそれに対応するパラメーターを使用して、実際のオブジェクトを作成し、すべてのパラメーターを設定します。この後、findViewById()を使用してUI要素への参照を取得できます。

私が読んだすべての記事で、convertviewがnullであるかどうかが最初に確認されるのはなぜですか?nullの場合はどういう意味ですか、そうでない場合はどういう意味ですか?

これは興味深いものです。ご覧のとおり、リスト内の項目が描画されるたびにgetView()が呼び出されます。ここで、アイテムを描画する前に、アイテムを作成する必要があります。現在、convertViewは基本的に、アイテムを描画するために最後に使用されたビューです。getView()では、最初にxmlを膨らませ、次にfindByViewID()を使用して、listitemのさまざまなUI要素を取得します。(convertView == null)をチェックする場合、ビューがnull(最初のアイテム)の場合は作成し、それ以外の場合は、ビューが既に存在する場合は再利用します。インフレートプロセスを再度実行する必要はありません。 。はるかに効率的になります。

getView()でViewHolderの概念に出会ったこともあります。これにより、リストがより効率的になります。ビューホルダーを作成し、インフレーション後に取得したすべてのUI要素への参照を保存します。このようにして、多数のfindByViewId()を呼び出さずに済み、時間を大幅に節約できます。このViewHolderは(convertView == null)条件で作成され、setTag()を使用してconvertViewに格納されます。elseループでは、getView()を使用して取得し、再利用します。

このメソッドが受け入れる親パラメーターは何ですか?

親は、getView()によって作成されたビューが最終的にアタッチされるViewGroupです。これであなたの場合、これはListViewになります。

お役に立てれば :)


4
  1. レイアウトインフレーターは、現在のビューに外部XMLをインフレート/追加します。

  2. getView()は、スクロールされたときを含め、何度も呼び出されます。したがって、すでにビューがインフレートされている場合は、インフレートはコストのかかるプロセスであるため、再度実行する必要はありません。

  3. 親ビューは、リストの単一セルです。


3
親ビューはここで誤って説明されています。それはListItemではなくListViewになります
Varun Jain '29

2

LayoutInflaterListViewアイテムまたはonCreateViewフラグメントのXMLの動的ビューを生成するために使用されます。

ConvertView基本的には、現在ビューにないビューをリサイクルするために使用されます。あなたがスクロール可能なものを持っているとしましょうListView。下または上にスクロールすると、スクロールされconvertViewたビューが表示されます。この再利用により、メモリが節約されます。

getView()メソッドの親パラメーターは、listViewを持つ親レイアウトへの参照を提供します。使用できる親XMLのアイテムのIDを取得するとします。

ViewParent nv = parent.getParent();

while (nv != null) {

    if (View.class.isInstance(nv)) {
        final View button = ((View) nv).findViewById(R.id.remove);
        if (button != null) {
            // FOUND IT!
            // do something, then break;
            button.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    Log.d("Remove", "Remove clicked");

                    ((Button) button).setText("Hi");
                }
            });
        }
        break;
    }

 }

1

getView()メソッドは、またはSpinnerの各行ごとに新規ViewまたはViewGroupを作成しますListview。これを定義するViewViewGroup、フォルダー内のLayout XMLファイルで定義しres/layoutて、AdapterクラスObject への参照を与えることができます。

配列に4つの項目がアダプタに渡されている場合。getView()メソッドは、Adaperの4行の4ビューを作成します。

LayoutInflaterクラスには、XMLリソースレイアウトからビューオブジェクトを作成するメソッドinflate()があります。


0

また、Adapter.javaファイルのAdapterインターフェースにgetViewに関する役立つ情報があります。それは言う;

/**
 * Get a View that displays the data at the specified position in the data set. You can either
 * create a View manually or inflate it from an XML layout file. When the View is inflated, the
 * parent View (GridView, ListView...) will apply default layout parameters unless you use
 * {@link android.view.LayoutInflater#inflate(int, android.view.ViewGroup, boolean)}
 * to specify a root view and to prevent attachment to the root.
 * 
 * @param position The position of the item within the adapter's data set of the item whose view
 *        we want.
 * @param convertView The old view to reuse, if possible. Note: You should check that this view
 *        is non-null and of an appropriate type before using. If it is not possible to convert
 *        this view to display the correct data, this method can create a new view.
 *        Heterogeneous lists can specify their number of view types, so that this View is
 *        always of the right type (see {@link #getViewTypeCount()} and
 *        {@link #getItemViewType(int)}).
 * @param parent The parent that this view will eventually be attached to
 * @return A View corresponding to the data at the specified position.
 */
View getView(int position, View convertView, ViewGroup parent);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.