2011-10-12 15 views
16

の動的リストを表示するのにFragmentActivityViewPagerを使用しようとしています。静的バージョンを実行する方法の例はたくさんあります。私の問題は、私が表示するリストを動的にロードする必要があり、ユーザーの入力(追加/削除)に基づいて変更することもできるということです。私はカスタマイズしたandroid.support.v4.content.Loaderを使用してリストを構築するために使用できるデータセットをロードしようとしています。Android - FragmentActivity + Loaderを使用してFragmentStatePagerAdapterを更新する際の問題

私は(FragmentStatePagerAdapterから)このコードが実行される時点で、アダプタと問題FragmentStatePagerAdapter#notifyDataSetChanged()コールを更新したいとき、私はポイントを取得するまで、すべてが私のセットアップで正常に行く

public void finishUpdate(View container) 
{ 
    if(mCurTransaction != null) 
    { 
     mCurTransaction.commit(); // BANG!!! The exception is thrown 
     mCurTransaction = null; 
     mFragmentManager.executePendingTransactions(); 
    } 
} 

トランザクションのコミットをして失敗しこのメッセージ:FragmentManagerImpl内のコードが実行される

java.lang.IllegalStateException: Can not perform this action inside of onLoadFinished

ため:

private void checkStateLoss() { 
    if (mStateSaved) { 
     throw new IllegalStateException(
       "Can not perform this action after onSaveInstanceState"); 
    } 
    if (mNoTransactionsBecause != null) { 
     throw new IllegalStateException(
       "Can not perform this action inside of " + mNoTransactionsBecause); 
    } 
} 

それはmNoTransactionsBecause値がnullでなく、結果は私が何とかtransaction.commitAllowingStateLoss()が関連すべてにtramsaction.commit()を変更しようと様々な変数を見ていたonLoadFinished

に戻されたとき、それはLoaderManagerImpl.LoaderInfoに設定されていることが判明しますトランザクションはプライベートであるか、少なくともパッケージで保護されているようです。

私は何をする必要があるのですか(そして、どうすればよいですか)。

だけではなく、Loaderを使用しての、私はあなたがFragmentStatePagerAdapterをコピーし、あなたが好きしかし、それを変更したり、ゼロから独自のPagerAdapterを作成することができますAsyncTask

+0

あなたはローダーでこれを行うための適切な方法を把握することができたことがありますか?私は同じ問題に直面している。私は 'transaction.commitAllowingStateLoss()'を使ってそれを動作させることができましたが、Googleが意図したことを知っていればいいです...データをロードした後にフラグメントトランザクションを実行する方法があるようですローダーを使用しています... – ashughes

+0

私はこれをあきらめて、限られたプールでModernTaskLoaderを使用しています – Bostone

+0

ModernTaskLoaderとは何ですか? – ashughes

答えて

35

私はこれと非常によく似た問題を抱えていましたが、断片のハンドラを使って解決しました。

私は、次の

public class MyFragment extends Fragment 
    implements LoaderManager.LoaderCallbacks<T> { 

    public void onLoadFinished(Loader<T> loader, T data) { 
     showDialog(); 
    } 

    public void showDialog() { 
     MyAlertDialogFragment fragment = new MyAlertDialogFragment(); 
     fragment.show(getActivity().getSupportFragmentManager(), "dialog"); 

    } 
} 

に似onLoadFinishedに警告ダイアログを()、見せたかった。しかし、これは

がonLoadFinished

の内部でこのアクションを実行することはできませんエラーが発生しました解決策は、ダイアログに表示するためにフラグメントにハンドラを追加することでした。

private Handler handler = new Handler() { 
    @Override 
    public void handleMessage(Message msg) { 
     if(msg.what == MSG_SHOW_DIALOG) { 
      showDialog(); 
     } 
    } 
}; 

そして代わりに

public void onLoadFinished(Loader<T> loader, T data) { 
     handler.sendEmptyMessage(MSG_SHOW_DIALOG); 
    } 
+11

または、ハンドラに実行可能ファイルを投稿します。 'ハンドラh =新しいハンドラ(Looper.getMainLooper()); h.post(新しいRunnable(){....}); 'など –

+1

@ Chris.Jenkins Ianの実装は、単一のオブジェクトの割り当てだけを必要とするため、より効率的です。 :) –

+0

@AlexLockwood高性能シナリオで1つのヒットで1000のオブジェクトを作成しない限り、実際問題はありません。 –

0

ローディングOPSを実行する場合、私のコードは正常に動作することに注意すること。または単にローダーを使用しないでください。

+0

これは、アダプタでは問題ありません。トランザクションをコミットしています。しかし、誰かがonLoadFinishedでのトランザクションコミットを防ぐためにかなりの努力を払っていました。なぜ私は知りたいのですか?私はまた、一行のためにクラスを書き直すのが好きではありません。そして、私はローダーコンセプトのように使いたいと思います。私が述べたように、私はAsyncTaskを直接使って実装を行っています – Bostone

+4

'onLoadFinished()'を呼び出すと状態が失われる可能性があるためです。 JavaDocから: 'この呼び出しでは、通常、アプリケーションは、アクティビティの状態が保存された後に発生する可能性があるため、フラグメントトランザクションをコミットすることはできません。詳細は、FragmentManager.openTransaction()を参照してください。 'あなたは 'commitAllowingStateLoss()'を使うためにアダプタに変更するか、ローダをスクラップする必要があります。私は同じ問題を抱えていましたが、私が得た答えは次のとおりです。https://groups.google.com/forum/#!topic/android-developers/dXZZjhRjkMk/discussion –

0

それはrootView.postを使用して動作しますハンドラにメッセージを送信するためにonLoadFinished(...)を変更します()。クラススコープでrootView変数を定義してから、それをonCreateView()で展開してください。最後にonLoadFinished ()は単にこのようにそれを使用します。

  rootView.post(new Runnable() { 
       public void run() { 
        General.showFragment(); 
       } 

      }); 
関連する問題