ドキュメントは、パラメーターのLayoutInflater.inflate目的について正確に明確ではありません。attachToRoot
attachToRoot : 膨張した階層をルート パラメーターにアタッチする必要があるかどうか。false の場合、ルートは XML のルート ビューの LayoutParams の正しいサブクラスを作成するためにのみ使用されます。
具体的には、ルート ビューとは何かを詳しく説明し、trueとfalse値の間の動作の変化の例を示してください。
ドキュメントは、パラメーターのLayoutInflater.inflate目的について正確に明確ではありません。attachToRoot
attachToRoot : 膨張した階層をルート パラメーターにアタッチする必要があるかどうか。false の場合、ルートは XML のルート ビューの LayoutParams の正しいサブクラスを作成するためにのみ使用されます。
具体的には、ルート ビューとは何かを詳しく説明し、trueとfalse値の間の動作の変化の例を示してください。
true に設定すると、レイアウトが膨張したときに、2 番目のパラメーターで子として指定された ViewGroup のビュー階層に自動的に追加されます。たとえば、ルート パラメータが のLinearLayout場合、膨張したビューはそのビューの子として自動的に追加されます。
false に設定されている場合、レイアウトは拡張されますが、他のレイアウトにはアタッチされません (したがって、描画されず、タッチ イベントなどを受け取りません)。
ドキュメントと前の2つの回答で十分なはずです。私からの考えだけです。
このinflateメソッドは、レイアウト ファイルを膨張させるために使用されます。これらの膨張したレイアウトでは、それらを親に直接アタッチするViewGroupか、そのレイアウト ファイルからビュー階層を膨張させて、通常のビュー階層の外で操作する必要があります。
最初のケースでは、attachToRootパラメーターを に設定する必要があります(または、レイアウト ファイルと親ルート(非) を受け取るメソッドをtrue使用するのは非常に簡単です)。この場合、返される は単にメソッドで渡された であり、インフレートされたビュー階層が追加されます。inflateViewGroupnullViewViewGroupViewGroup
2 番目のオプションでは、レイアウト ファイルViewのルートが返されます。ペアの質問ViewGroupからの最後の議論を覚えているなら、これがの制限の理由の 1 つです(ルートとしてのレイアウト ファイルが膨張する場合、親を指定し、に設定する必要があります)。ルート aタグを含むレイアウト ファイルがあり、それに設定されていた場合、メソッドには同等のものがないため、何も返されません。また、ドキュメントにあるように、正しいバージョンでビュー階層を作成できるため、に設定されたバージョンが重要ですinclude-mergemergemergeattachedToRoottruemergeattachedToRootfalseinflatemergeinflateattachToRootfalseLayoutParams親から。これは場合によっては重要であり、メソッド セットがサポートされていないAdapterViewのサブクラスであるの子で最も顕著です。メソッドで次の行を使用したことを覚えていると思います。ViewGroupaddView()getView()
convertView = inflater.inflate(R.layout.row_layout, parent, false);
この行により、インフレートされたファイルのルートに設定されたサブクラスからR.layout.row_layoutの正しいものが確実に含まれるようになります。これを行わないと、ルートが. また、いくつかの特別で重要なものがあり、それらのビューに正しい.LayoutParamsAdapterViewViewGroupRelativeLayoutTableLayout/TableRowLayoutParamsLayoutParams
この回答を書いたのは、いくつかの StackOverflow ページを通過した後でも、 attachToRoot の意味を明確に把握できなかったからです。以下は、LayoutInflater クラスの inflate() メソッドです。
View inflate (int resource, ViewGroup root, boolean attachToRoot)
私が作成したactivity_main.xmlファイル、button.xmlレイアウト、およびMainActivity.javaファイルを見てください。
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
ボタン.xml
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LayoutInflater inflater = getLayoutInflater();
LinearLayout root = (LinearLayout) findViewById(R.id.root);
View view = inflater.inflate(R.layout.button, root, false);
}
コードを実行すると、レイアウトにボタンが表示されません。これは、attachToRoot が false に設定されているため、ボタン レイアウトがメイン アクティビティ レイアウトに追加されていないためです。
LinearLayout には、ビューを LinearLayout に追加するために使用できるaddView(View view)メソッドがあります。これにより、ボタン レイアウトがメイン アクティビティ レイアウトに追加され、コードの実行時にボタンが表示されます。
root.addView(view);
前の行を削除して、attachToRoot を true に設定するとどうなるか見てみましょう。
View view = inflater.inflate(R.layout.button, root, true);
ここでも、ボタン レイアウトが表示されていることがわかります。これは、 attachToRoot が指定された親にインフレートされたレイアウトを直接アタッチするためです。この場合、ルート LinearLayout です。ここでは、前のケースで addView(View view) メソッドを使用して行ったように、手動でビューを追加する必要はありません。
フラグメントに対して attachToRoot を true に設定すると、IllegalStateException が発生するのはなぜですか。
これは、フラグメントのレイアウトをアクティビティ ファイル内のどこに配置するかを既に指定しているためです。
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.add(R.id.root, fragment)
.commit();
add(int parent, Fragment fragment)は、レイアウトを持つフラグメントを親レイアウトに追加します。attachToRoot を true に設定すると、IllegalStateException: The specified child already has a parent が発生します。フラグメント レイアウトは、add() メソッドで親レイアウトに既に追加されているためです。
Fragments をインフレートするときは、常に attachToRoot に false を渡す必要があります。フラグメントを追加、削除、置換するのは FragmentManager の仕事です。
私の例に戻ります。両方やったらどうでしょう。
View view = inflater.inflate(R.layout.button, root, true);
root.addView(view);
最初の行で、LayoutInflater はボタン レイアウトをルート レイアウトにアタッチし、同じボタン レイアウトを保持する View オブジェクトを返します。2 行目では、同じ View オブジェクトを親ルート レイアウトに追加します。これにより、フラグメントで見たのと同じ IllegalStateException が発生します (指定された子には既に親があります)。
デフォルトで attachToRoot を true に設定する別のオーバーロードされた inflate() メソッドがあることに注意してください。
View inflate (int resource, ViewGroup root)
attachToRoottrue に設定するinflatedViewと、 が親ビューの階層に追加されます。したがって、ユーザーがタッチ イベント (またはその他の UI 操作) を「見て」感知する可能性があります。それ以外の場合は、作成されたばかりで、どのビュー階層にも追加されていないため、タッチ イベントを表示したり処理したりできません。
Android を初めて使用する iOS 開発者attachToRootの場合、true に設定すると、次のメソッドが呼び出されます。
[parent addSubview:inflatedView];
さらに進むと、次のように尋ねるかもしれません: に設定attachToRootした場合、親ビューを渡す必要があるのはなぜfalseですか? これは、XML ツリーのルート要素が親ビューでいくつかの LayoutParams を計算する必要があるためです (親の一致など)。
親を定義すると、 attachToRoot は、インフレータが実際に親にアタッチするかどうかを決定します。場合によっては、これにより問題が発生します。ListAdapter のように、リストがビューをリストに追加しようとして例外が発生しますが、既にアタッチされていると表示されます。ビューを自分で膨張させてアクティビティに追加するだけの場合は、便利でコード行を節約できます。