14

Fragments向きの変更に問題があります。

タブ付きのアクションバーを介してMainActivity切り替えを処理するアプリケーションがあります。Fragmentsタブ付きアクション バーのコードと、タブが選択されたときのコードを次に示します。

private class MyTabListener <T extends android.support.v4.app.Fragment> implements ActionBar.TabListener {
    private android.support.v4.app.Fragment mFragment;
    private final Activity mActivity;
    private final String mTag;
    private final Class<T> mClass;

    public MyTabListener(SherlockFragmentActivity activity, String tag, Class<T> clz) {
        mActivity = activity;
        mTag = tag;
        mClass = clz;
    }

    @Override
    public void onTabSelected(Tab tab, android.support.v4.app.FragmentTransaction ft) {
        if (mFragment == null){ // check to see if the fragment has already been initialised. If not create a new one.
            mFragment = android.support.v4.app.Fragment.instantiate(mActivity, mClass.getName());
            ft.add(android.R.id.content,mFragment,mTag);
        } else {
            ft.attach(mFragment); // if the fragment has been initialised attach it to the current activity
        }
    }

    @Override
    public void onTabUnselected(Tab tab, android.support.v4.app.FragmentTransaction ft) {
        if (mFragment != null){
            ft.detach(mFragment); // when a fragment is no longer needed, detach it from the activity but dont destroy it
        }
    }

    @Override
    public void onTabReselected(Tab tab, android.support.v4.app.FragmentTransaction ft) {

    }

私の見方では、アプリケーションが最初にポートレート モードで読み込まれると、すべてが正常に機能します。回転すると、何らかの理由で の別のインスタンスFragment1が追加され、別のタブが選択されたときにデタッチされません。これは、縦向きに戻す場合にも当てはまります。

setRetainInstance(true);私は自分で使用しようとしましたFragmentsが、これは機能しません。

Fragments回転する前にオーバーライドまたは何かをする必要がある方法はありますか?

前もって感謝します。

EDITアクティビティが再作成されると、onTabSelectedが再度呼び出されることがわかりました。これが、フラグメントが複数回添付されるという問題の原因でしょうか?

これが私の活動 onCreate メソッドです。

super.onCreate(savedInstanceState);

        if (savedInstanceState == null) {
           //setContentView(R.layout.main);

        }
     // Create the Action Bar with tabs
        ActionBar actionBar = getSupportActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        actionBar.setDisplayShowTitleEnabled(false);
        //create the tab for track and add it to the action bar.
        Tab tab = actionBar.newTab()
                            .setText("Track")
                            .setTabListener(new MyTabListener<TrackingFragment>(this,"track",TrackingFragment.class));
        actionBar.addTab(tab);

        //create the tab for ski tracks and add it to the action bar.
        tab = actionBar.newTab()
                        .setText("Something Tracks")
                        .setTabListener(new MyTabListener<TrackListFragment>(this,"somethingtracks",TrackListFragment.class));
        actionBar.addTab(tab);

        //create the tab for photos and add it to the action bar.
        tab = actionBar.newTab()
                        .setText("Photos")
                        .setTabListener(new MyTabListener<PhotoFragment>(this,"photos",PhotoFragment.class));
        actionBar.addTab(tab);
4

5 に答える 5

16

簡単な修正:

このonTabSelectedメソッドでは、使用する前if (mFragment == null)にフラグメントを取得する必要があります ( を使用mFragment = getSupportFragmentManager().findFragmentByTag(mTag))。これを外部から設定することもできますが、これを行っているのは見られません。

チェックif(savedInstanceState == null)するonCreateことでこれを解決することもできますが、より良いアプローチだと思います! :)

于 2012-06-18T15:37:12.113 に答える
8

onCreateメソッドに でラップされたものがないように聞こえるif(savedInstanceState == null)ので、savedInstanceState バンドルから復元されたものに加えて、別のフラグメントを作成しています。

編集

コードを詳しく見てみると、onCreate について間違っていたと思います。onTabSelected で処理する必要があります。if (mFragment == null)フラグメントを見つけようとしないため、常にnullになると思います。そのコード セクションを次のように変更します。

@Override 
public void onTabSelected(Tab tab, android.support.v4.app.FragmentTransaction ft) { 

    mFragment = mActivity.getSupportFragmentManager().findFragmentByTag(mTag);   // add this

    if (mFragment == null){ // check to see if the fragment has already been initialised. If not create a new one. 
        mFragment = android.support.v4.app.Fragment.instantiate(mActivity, mClass.getName()); 
        ft.add(android.R.id.content,mFragment,mTag); 
    } else { 
        ft.attach(mFragment); // if the fragment has been initialised attach it to the current activity 
    } 
} 
于 2012-06-18T15:05:09.873 に答える
1

私は多かれ少なかれ同じ問題を抱えていましたが、上記の解決策は私の状況ではうまくいかないようでした. 最終的に、次の解決策を見つけました。

@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
    if (mFragment == null) {
        mFragment = Fragment.instantiate(mActivity, mClass.getName());
        ft.replace(android.R.id.content, mFragment, mTag); // Use replace iso add
    }
    else {
        ft.attach(mFragment);
    }
}
于 2013-06-16T22:50:15.640 に答える
0

if(savedInstanceState == null)が常に機能しているわけではありません。横向きのために別のフラグメントを追加する必要があるときに、savedInstanceState!=nullになることがあります。

別のアプローチは、方向が何であれ、fm.findFragmentById(R.id.frameLayoutLeft)がnullであるかどうかをテストすることです。そうでない場合は、新しいフラグメントインスタンスを作成し、それ以外の場合は何もしません。ランドスケープモードで2番目のフラグメントが必要な場合は、最初にランドスケープかどうかを確認する必要があります。必要な場合は、fm.findFragmentById(R.id.frameLayoutRight)がnullかどうかを確認してください。nullの場合は、作成するよりも、それ以外の場合は、Android OSによってすでに保持されているため、何もしません。

于 2013-02-06T16:50:51.047 に答える