2

一連のデータを収集する asynctask を実行するこのアクティビティがあります。このデータはいくつかの方法で表すことができます。簡単にするために、2 つの方法があるとします。ユーザーがこれら 2 つの表現 (リストビューとグラフィカル ビュー) を切り替えられるようにしたいと考えています。

そこで、ListFragment と GraphicFragment を使用して FragmentActivity を作成しました。

ユーザーが前後に移動できるように、これら 2 つを切り替えるにはどうすればよいでしょうか。置換を使用してみましたが、以前のフラグメントが破棄されますが、その参照にはアクティビティによって渡されたデータがあるため、これは私の興味ではありません。(つまり、ユーザーがビューを切り替えるたびにフラグメントを再作成したくありません)。

非表示と表示も試しましたが、機能しません。フラグメントの1つが表示されていません。

また、回転すると、フラグメントにアクセスしようとするとnullpointerexceptionが発生するため、フラグメントが破壊されると思います。

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

    pBar = (ProgressBar) findViewById(R.id.analyzingProgress);

    // However, if we're being restored from a previous state, then don't
    // create the fragment again (please)
    if (savedInstanceState == null) {

        firstFragment = new DirListFragment();
        secondFragment = new GraphViewFragment();

                         getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, secondFragment).commit();


        fragments= new ArrayList<IFragment>();
        fragments.add(firstFragment);
        fragments.add(secondFragment);
    }
}


    @Override
public boolean onOptionsItemSelected(MenuItem item) {
    if(item.getItemId() == R.id.listView){

        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

        /*transaction.hide(secondFragment);         
        transaction.show(firstFragment);*/
        transaction.replace(R.id.fragment_container, firstFragment);
        transaction.addToBackStack(null);

        transaction.commit();
    }
    else if(item.getItemId() == R.id.graph){
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        /*transaction.hide(firstFragment);
        transaction.show(secondFragment);*/
        transaction.replace(R.id.fragment_container, secondFragment);
        transaction.addToBackStack(null);

        transaction.commit();
    }
    return true;
}

問題は、フラグメント フィールドにアクセスしてデータを更新しようとしたときに発生します。

     for(IMyFragment frag: fragments){
        frag.updateData(data);
    }

画面を回転させた後、NullPointerException が発生します。

また、フラグメントを切り替えても、それらのデータは更新されません (つまり、リストフラグメントから始めて、適切なデータを表示し、次にグラフィックに切り替え、データが表示されず、リストに切り替えて、再びデータがありません。)

4

1 に答える 1

2

を使用するときにフィールドが null の場合setRetainInstance(true);、アクティビティでフィールド (フラグメント) を再作成しています。onSaveInstanceState()アクティビティに何かを設定していることを確認して、 in が nullonCreate()savedInstanceStateならないようにしてください。空のバンドルまたは役に立たない変数になることもあります。例:

@Override
public void onSaveInstanceState(Bundle outstate){
    super.onSaveInstanceState(outstate);
    outstate.putBoolean("stateChanged", true);
}

引数を追加する前に必ず super を呼び出してください。

別の注意として、私は個人的にフラグメントを配列に保存したことがありません。FrameLayoutあなたと同じように、アクティビティでフラグメントコンテナとして aを使用します。何かを更新する必要がある場合は、呼び出すだけです。getSupportFragmentManager().findFragmentById(R.id.fragment_container).setWhatINeed();この方法で、常に表示されているフラグメントを取得します。

更新がどのように行われるか教えてください。私ができる限りの情報でこの投稿を更新します。

于 2013-03-09T21:12:47.040 に答える