LayoutInflaterが、指定したlayout_widthおよびlayout_heightレイアウトパラメーターを無視するのはなぜですか?


168

LayoutInflaterを期待どおりに動作させるのに深刻な問題がありました。他の人もそうでした。layoutinflatorを使用して実行時にビューを追加する方法は?

LayoutInflaterが指定したレイアウトパラメータを無視するのはなぜですか?例えば、なぜされているlayout_widthlayout_height、私のリソースXMLからの値光栄ではありませんか?


本当-それは痛いですか、それとも私は間違った場所を選びましたか?結果を共有したいと思いました。チュートリアルが具体的に.. FAQページで言及されていない認めなければならない
andig

3
よくある質問の最初の質問の最後の段落を参照してください。質問として投稿してから、チュートリアルを回答として投稿してください。もちろん、この質問を編集して、回答にチュートリアルをカットアンドペーストできます。これを修正したら賛成します。
bigstones 2011

回答:


381

この問題については、LayoutInflaterのドキュメントを参照し、小さなサンプルデモプロジェクトを設定して調査しました。次のチュートリアルは、を使用してレイアウトを動的に入力する方法を示していますLayoutInflater

始める前に、LayoutInflater.inflate()パラメーターがどのように見えるかを確認します。

  • リソース:負荷へのXMLレイアウトリソースのID(例えば、R.layout.main_page
  • ルート:オプション発生階層の親するビュー(存在する場合attachToRootであるtrue)、あるいは一連の提供単にオブジェクトLayoutParams返される階層のルートの値を(場合attachToRootですfalse。)
  • attachToRoot:膨張した階層をルートパラメータにアタッチする必要があるかどうか。falseの場合、ルートはLayoutParamsXMLのルートビューの正しいサブクラスを作成するためにのみ使用されます。

  • 戻り値:膨張した階層のルートビュー。根が供給された場合attachToRoottrue、これはrootです。それ以外の場合は、インフレートされたXMLファイルのルートです。

次に、サンプルのレイアウトとコードについて説明します。

メインレイアウト(main.xml):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</LinearLayout>

このコンテナに追加されたのは、レイアウトパラメータがXMLから正常に適用された場合に小さな赤い正方形として表示される個別のTextViewです(red.xml):

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="25dp"
    android:layout_height="25dp"
    android:background="#ff0000"
    android:text="red" />

今すぐLayoutInflaterコール・パラメータのいくつかのバリエーションが使用されています

public class InflaterTest extends Activity {

    private View view;

    @Override
    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

      setContentView(R.layout.main);
      ViewGroup parent = (ViewGroup) findViewById(R.id.container);

      // result: layout_height=wrap_content layout_width=match_parent
      view = LayoutInflater.from(this).inflate(R.layout.red, null);
      parent.addView(view);

      // result: layout_height=100 layout_width=100
      view = LayoutInflater.from(this).inflate(R.layout.red, null);
      parent.addView(view, 100, 100);

      // result: layout_height=25dp layout_width=25dp
      // view=textView due to attachRoot=false
      view = LayoutInflater.from(this).inflate(R.layout.red, parent, false);
      parent.addView(view);

      // result: layout_height=25dp layout_width=25dp 
      // parent.addView not necessary as this is already done by attachRoot=true
      // view=root due to parent supplied as hierarchy root and attachRoot=true
      view = LayoutInflater.from(this).inflate(R.layout.red, parent, true);
    }
}

パラメータのバリエーションの実際の結果は、コードに記載されています。

SYNOPSIS:呼び出すLayoutInflaterXMLからレイアウトパラメータを無視するのinflateコールにルートリードを指定せずに。ルートが等しくない状態でinflateを呼び出すnullattachRoot=true、レイアウトパラメータは読み込まれますが、ルートオブジェクトが再び返されます。これにより、読み込まれたオブジェクトのレイアウトがそれ以上変更されなくなります(を使用してそれを見つけることができない場合findViewById())。したがって、使用する可能性が最も高い呼び出し規約は次のとおりです。

loadedView = LayoutInflater.from(context)
                .inflate(R.layout.layout_to_load, parent, false);

レイアウトの問題を解決するために、レイアウトインスペクターを強くお勧めします。


20
すばらしい答えです。3年間Androidの開発に取り組んでおり、それを数え続けていますが、このことから学ぶことはまだありました。
Reuben Scratton 2012

こんにちは、R.layoutでインフレートする代わりに、Javaコードで同じことを行う方法はありますか。レイアウトがないので。Javaコードでビューを作成しましたが、同じビューを300回追加したいと思います。
Raj

1
@andig:ActivityのサブクラスであるContextと答えの例は、の範囲にあるActivityので、それを簡単にするために、私は交換しgetBaseContext()this、この答えのために、それは同等だ、と。
Marcin Orlowski、2014年

5
コンテナーのlayout_widthとlayout_heightは "match_parent"に設定されています。次に、コメントは「//結果:layout_height = wrap_content layout_width = match_parent」と言います。sthが欠けていますか?
MarianPaździoch15年5

1
調査を行い、結果を共有していただきありがとうございます。また、私はマリアンの質問に答えます。
LarsH

5

andigは正解です。LayoutInflaterがlayout_paramsを無視する一般的な理由は、ルートが指定されていないためです。多くの人々は、あなたがルートにヌルを渡すことができると思います。これは、作成時にrootにアクセスできないダイアログなどのいくつかのシナリオでは許容されます。ただし、従うべき良いルールは、rootがある場合は、それをLayoutInflaterに渡すことです。

私はこれについて詳細なブログ投稿を書きました。ここでチェックできます:

https://www.bignerdranch.com/blog/understanding-androids-layoutinflater-inflate/


1
This is acceptable for a few scenarios such as a dialogそれが私が必要としていたすべてでした
rookieDeveloper

0

上記のメインの回答に追加したいのです
が、フォローしようとしましたが、recyclerViewがすべてのアイテムを画面
に 引き伸ばし始めました。

itemLayoutView.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT));

私はすでにこれらのパラメータをxmlで追加しましたが、正しく機能しませんでした。
この行ではすべて問題ありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.