1

私は、私のUXフローのセクションを持っています。ここでは、ユーザーのためのメッセージをテキストビューで2秒間フラグメントAに表示し、その後にフラグメントAをフラグメントBに置き換えます。これは、フラグメントA.Android:X秒後に別のフラグメントに移動しますか?

someTextView.setText("some message"); 

Handler mainLooperHandler = new Handler(Looper.getMainLooper()); 

mainLooperHandler.postDelayed(new Runnable() { 
       @Override 
       public void run() { 
        ((MyActivity) getActivity()).gotoTheNextFragment(); 
       } 
      }, 2000); 

そして、私の活動の関連するメソッド:

public void gotoTheNextFragment() { 
    Fragment mFragmentB = new FragmentB(); 

    getSupportFragmentManager().beginTransaction() 
      .replace(R.id.fragmentContainer, mFragmentB, "FRAGMENTB") 
      .commit(); 
} 

は、しかし、これはいくつかの問題が発生します。まず、遅延後の実行中にユーザが「戻る」を押すと、ユーザはgetActivityでnullポインタ例外を取得します。第2に、転送を実行しようとしているときに、ユーザーが「onSaveInstanceStateの後にこのアクションを実行できません」というエラーを取得することがあります。

私は 'commit'を 'commitAllowingStateLoss'に変更すると2番目のエラーを回避できますが、これはおそらくベストプラクティスではなく、asynctask内のフラグメント間の移動はお勧めします。このプロセスを達成するためのより良い方法は何ですか(メッセージを表示して2秒待ってから、クラッシュに至らない安全な方法でフラグメントを置き換えてください)。

+0

Context.sendBroadcast(またはその他の通知方法)を試して、フラグメンテーションを変更することをアクティビティに通知しましたか?このようにして、あなたはあなたのアクティビティに、遷移中に何ができるのかを制限する変数を持たせることができますか? – zveljkovic

+0

あなたのフラグメントのonDestroyView()でHandlerタスクをキャンセルしないのはなぜですか? –

+0

私たちが準備しているか、ユーザーが背中を押したり、迷惑をかけることがないように、待っているようなメッセージをスヌーキーバーまたはトーストで使用してください。 – androidnoobdev

答えて

0

最後に、私はこのようにそれをしなかったので、それは良い練習と考えられていないので、私はcommitAllowingStateLossを使用して避けたかった:

がフラグメントと活性との間のインタフェースを定義し、活動中のインタフェースを実装しました。アクティビティは、インタフェースを介してメッセージを受信すると、フラグメントトランザクションを開始します。これは、たとえonPauseを実行して同じonSaveInstanceStateエラーを取得したとしても、フラグメントを変更する応答が到着するため、問題を引き起こします。アクティビティがonPauseであった場合にチェックを追加できましたが、フラグメントを変更するメッセージが失われてしまい、ユーザーは元のフラグメントの代わりに元のフラグメントを再開しました。

したがって、最終的な解決策は、2つのブール値を定義することでした。最初のブール値は、アクティビティの状態を追跡することです。

private boolean activityIsPaused = false; 

はonPauseでtrueに設定され、onResumeではfalseに設定されます。ブール値が偽であり、答えがインタフェースを介して返された場合は、すぐにフラグメントトランザクションを実行します。しかし、ブール値がtrueに設定されている場合は、別のブール値を設定します。たとえば、wantsToPerformFragmentTransaction - をtrueに設定します。 onResumeFragmentsでは(もしonResumeでもうまく動作します - 私はチェックしませんでした)、boolean wantsToPerformFragmentTransactionがtrueならfalseに設定してフラグメントトランザクションを実行します。

結果:エラーは発生せず、commitAllowingStateLossは使用されず、ユーザーは表示されるはずのフラグメントをユーザーが見たときに一貫した結果が得られます。

0

アクティビティでgotoTheNextFragmentメソッドを定義する必要はありません。フラグメント内でそれを自分で定義することができます。

someTextView.setText("some message"); 

Handler mainLooperHandler = new Handler(Looper.getMainLooper()); 

mainLooperHandler.postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       if(getActivity!=null){ 

       Fragment mFragmentB = new FragmentB(); 

       getActivity().getSupportFragmentManager().beginTransaction() 
       .replace(R.id.fragmentContainer, mFragmentB, "FRAGMENTB") 
       .commit(); 
      } 
      } 
     }, 2000); 
+0

どうすればそれが役に立ちますか? –

+0

さて、少なくともNPEは避けてください:) –

+0

これは両方の問題を解決します.getactivity()をチェックしていません。nullではありません。 – Dharmaraj

0

初めてアクティビティインスタンスを返すので、getActivity()は使用しないでください。それ以外の場合はnullを返します。したがって、そのインスタンスをonAttach()のフラグメントのメソッドに格納し、それを任意の目的に使用します。

あなたが後方に移行しながら、それはNullPointerExceptionが解決しなければならない。このようにそれを使用します。このようにそれを使用しても、「後にこのアクションを実行することはできませんためcommitAllowingStateLossを使用)

public class YourFragment extends Fragment { 

private Activity _activity; 

@Override 
public void onAttach(Activity activity) { 
    super.onAttach(activity); 
    _activity = getActivity(); 
} 

} 

をだから今の代わりにgetActivityを(使用しますonSaveInstanceState "エラーです。

Fragment mFragmentB = new FragmentB(); 

_activity.getSupportFragmentManager().beginTransaction() 
     .replace(R.id.fragmentContainer, mFragmentB, "FRAGMENTB") 
     .commitAllowingStateLoss(); 
関連する問題