13

階層を減らすために階層ビューアーを使用しているときに、フラグメントを追加するたびに (「静的」または「動的」の両方の方法で) フラグメントが常に新しい FrameLayoutにラップされることに気付きました。

次に例を示します。

これは私の活動のレイアウトです:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="mainActivityRoot" >

<TextView
    android:id="@+id/hello_world"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello_world" />

<fragment
    android:name="com.example.testfragments.MainFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/hello_world" />

</RelativeLayout>

そして、これはフラグメントのレイアウトです:

<ProgressBar android:id="@+id/ProgressBar1" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:contentDescription="mainFragmentRoot"
android:layout_height="match_parent" />

アクティビティのソース コードは 以外は空ですsetContentView, フラグメントのソース コードには のみが含まれます

@Override
public View onCreateView(...) {
    return inflater.inflate(R.layout.fragment_main, container, false);
}

今、

アクティビティ ルートの階層に直接表示されることを期待しますがPrograssBar、その代わりに、どこから来たのかわからない追加の FrameLayout があります。余分なフレームを黄色でペイントしたスクリーン ショットを次に示します。 ビュー階層をダンプします - 黄色は悪いです

それで、私の質問は - それはどこから来たのですか? そして、私はそれを取り除くことができますか? 私の実際のアプリケーションでは、これらの余分な FrameLayout が非常に深い階層を作成しており、おそらくパフォーマンスが低下しています。

ありがとう!

4

1 に答える 1

12

あなたはサポート v4 ライブラリを使用しているようで、フラグメント xml タグに id を入れるのを忘れていました:)、そう:

それはどこから来たのか?

これはFragmentManager の 888 行目から来ており、ここでこれを見ることができます:

f.mView = NoSaveStateFrameLayout.wrap(f.mView);

この理由は下位互換性であり、次のようなコメント ヘッダーでより適切に説明されてNoSaveStateFrameLayoutいます。

/**
 * Pre-Honeycomb versions of the platform don't have {@link View#setSaveFromParentEnabled(boolean)},
 * so instead we insert this between the view and its parent.
 */

私はそれを取り除くことができますか?

さて、私は3つのオプションを考えることができます:

  1. このコンテナーを省略した v4 ライブラリ バージョンのサポートに基づいて独自の実装を行うこともできますがFragmentManager、そのコードを作成/維持する労力は価値がないと思います。さらに、これらFrameLayoutの s によるオーバーヘッドが巨大になるとは思いません、パフォーマンスの問題が発生している場合はView、これ以外に実行する最適化が他にある可能性があります (カスタム ビューを作成するextends Viewなど)。または、レイアウト/フラグメントを再考して、特定の時点で階層内のビューの量を減らすと言います。
  2. 1.を達成するサポート v4 ライブラリの新しいリリースを待ちます。 <- うん、私は怠け者です :D、まだバグがない場合はバグを報告する必要があります ( 3.を参照) 。自分のパッチや他の誰かに貢献することもできます。
  3. サポート v4 ライブラリが (より長く) 必要とされないプラットフォームのみをサポート (またはそれまで待機)FragmentManagerますViewGroupFragmentManager

お母さん、ネストされた <code>FrameLayout</code> はありません!!1

その時間を投資できる他の最適化があると述べたので、私はそれらについてあまり心配しません;)

于 2013-05-27T17:09:03.470 に答える