29

getChildFragmentManager()プログラムで (動的に) 追加されたsを使用する (または「使用できますか」) 方法はFragment?

これが私の例です。

私は 1 MainActivity、 1 OuterFrag、 1 を持っていInnerFragます。によって動的に を追加OuterFragします。また、によって動的ににも を追加します。しかし、私は の子として正確に追加し、置き換えずに の新しい子にしたいと考えています。MainActivityFragmentManagerInnerFragOuterFragFragmentManagerInnerFragOuterFragOuterFragMainActivity

この階層を維持したい: MainActivity -> OuterFrag -> InnerFrag. したがって、MainActivity は常に OuterFrag を呼び出すことができます。

ただし、この階層から変更しないでください: この階層MainActivity -> OuterFragに変更MainActivity -> InnerFragするMainActivityと、OuterFrag.

これが私のコード例です。

MainActivity.java

package com.example.frag;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;

public class MainActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getSupportFragmentManager().beginTransaction().add(R.id.frameLayout, new OuterFrag()).commit();
        getSupportFragmentManager().executePendingTransactions();

        System.out.println("Before: "
                + getSupportFragmentManager().findFragmentById(R.id.frameLayout));

        ((OuterFrag) getSupportFragmentManager().findFragmentById(R.id.frameLayout))
                .addInnerFrag();

        System.out.println("After: "
                + getSupportFragmentManager().findFragmentById(R.id.frameLayout));
    }
}

activity_main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/frameLayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
</FrameLayout>

OuterFrag.java

package com.example.frag;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class OuterFrag extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.outer_frag, container, false);
    }

    public void addInnerFrag() {

        getFragmentManager().beginTransaction().replace(this.getId(), new InnerFrag()).commit();
        getFragmentManager().executePendingTransactions();

//        getChildFragmentManager().beginTransaction().add(this.getId(), new InnerFrag()).commit();
//        getChildFragmentManager().executePendingTransactions();
    }
}

outer_frag.xml

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="i am the OUTER frag" />

InnerFrag.java

package com.example.frag;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class InnerFrag extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.inner_frag, container, false);
    }
}

inner_frag.xml

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/textView2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="i am the INNER frag" />

現在、上記のコードはエラーなしで実行できます。しかし、実際にInnerFragは の新しい子として変化していMainActivityます。これは、Before: Object と After: Object が変更された 2 つの System Print Out ステートメントによって確認できます。でOuterFrag.java、ステートメントgetChildFragmentManager()の代わりにステートメントを実行するgetFragmentManager()と、次のランタイム エラーが発生します。

12-07 02:29:38.406: E/AndroidRuntime(12051): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.frag/com.example.frag.MainActivity}: java.lang.IllegalArgumentException: No view found for id 0x7f070000 (com.example.frag:id/frameLayout) for fragment InnerFrag{46e32748 #0 id=0x7f070000}

を使用するgetChildFragmentManager()ことは、理論的には正しいです。非プログラム的に追加されたフラグメントで使用できます (つまり、 を に変更し、 attribute を追加し、activity_main.xmlの最初のステートメントを削除します)。そして、正しい階層を維持しています: . しかし、元のフラグメント ( ) の単語は決して取り除くことはできません。<FrameLayout><fragment>android:name="com.example.frag.OuterFrag"getSupportFragmentManager()MainActivity.javaMainActivity -> OuterFrag -> InnerFragouter_frag.xml

結論として、常に参考OuterFragにしたい。そして、さまざまなsをロードするプレースホルダーとして機能しMainActivityたいと考えています。つまり、プログラムで (動的に) 追加されたときに、を呼び出したいのです。OuterFragInnerFraggetChildFragmentManager()OuterFrag

4

2 に答える 2

45

結論として、私は常にMainActivityでOuterFragを参照したいと思います。そして、OuterFragをプレースホルダーとして機能させてさまざまなInnerFragをロードしたいと思います。つまり、プログラムで(動的に)追加されたときに、OuterFragでgetChildFragmentManager()を呼び出したいと思います。

これが必要な場合はOuterFrag、コンテンツとしてコンテナレイアウトを作成し、そのInnerFragコンテナに何でも追加します。のレイアウトファイルは次のOuterFragようになります。

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragContainer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
/>

もちろん、必要に応じて、レイアウトに他のビューを含めることもできますOuterFrag。次に、addInnerFragメソッドは次のようになります。

public void addInnerFrag() {
        getChildFragmentManager().beginTransaction().add(R.id.fragContainer, new InnerFrag()).commit();
        getChildFragmentManager().executePendingTransactions();
}

OuterFragメインアクティビティにを追加するためのコードは引き続き有効です。

于 2012-12-07T06:29:55.800 に答える
-1

addInnerFrag()コード内で呼び出したい場合はOuterFrag.java、次のように実行できます。

OuterFrag.java:

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    addInnerFrag();
}
于 2016-06-09T13:33:45.603 に答える