2013-03-17 74 views
14

NFCを使用して、そこに格納されているデータを読み取るアプリケーションを作成しています。私のアプリケーションでは、フラグメントとフラグメントはonNewIntent()メソッドに付属していません。私が読んでいるデータは、NFC関連の操作を扱う私の別のクラスで行われるので、私がする必要があるのは、フラグメント内のTextViewを更新することだけです。ただし、このインプリメンテーションを使用して、新しいIntentをFragmentに渡すこともできます。フラグメント内のonNewIntentの処理

ここに私の現在の実装があり、これはインターフェイスを利用しています。新しいIntentが受信され、NFC関連のチェックが成功した後、リスナーに電話しています。これは、FragmentをホストするFragmentActivityです。

public class Main extends FragmentActivity implements 
    ActionBar.OnNavigationListener { 

private Bundle myBalanceBundle; 
private NFC nfcObj; 
private NewBalanceListener newBlanceListener; 

@Override 
public void onNewIntent(Intent intent) { 
    setIntent(intent); 
} 

@Override 
protected void onResume() { 
    getNFCState(); 
    super.onResume(); 
} 

private void getNFCState() { 
    //Other NFC related codes 
    else if (nfc_state == NFC.NFC_STATE_ENABLED){ 
     readNFCTag(); 
    } 
} 

private void readNFCTag() { 
    //Other NFC related codes 
    if (getIntent().getAction().equals(NfcAdapter.ACTION_TECH_DISCOVERED)) { 
     nfcObj.setTag((Tag) getIntent().getParcelableExtra(
       NfcAdapter.EXTRA_TAG)); 
     nfcObj.readQuickBalance(); 

     transitQuickReadFragment(nfcObj.getCurrentBalance()); 
    } 
} 

private void transitQuickReadFragment(String balance) { 
    // Creates a balance bundle and calls to select MyBalance Fragment if it 
    // is not visible. Calls listener is it is already visible. 
    if (actionBar.getSelectedNavigationIndex() != 1) { 
     if (myBalanceBundle == null) 
      myBalanceBundle = new Bundle(); 

     myBalanceBundle.putString(Keys.BALANCE.toString(), balance); 

     actionBar.setSelectedNavigationItem(1); 
    } else { 
     newBlanceListener.onNewBalanceRead(balance); 
    } 
} 

@Override 
public boolean onNavigationItemSelected(int position, long id) { 
    // Other fragment related codes 
    fragment = new MyBalance(); 
    fragment.setArguments(myBalanceBundle); 
    newBlanceListener = (NewBalanceListener) fragment; 
    // Other fragment related codes 
} 

// Interface callbacks. You can pass new Intent here if your application 
// requires it. 
public interface NewBalanceListener { 
    public void onNewBalanceRead(String newBalance); 

} 
} 

これは、NFCが読み込まれるたびに更新する必要があるのTextViewを持ってMyBalance断片である:

public class MyBalance extends Fragment implements NewBalanceListener { 

private TextView mybalance_value; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    //Other onCreateView related code 

    Bundle bundle = this.getArguments(); 
    if (bundle != null) 
     mybalance_value.setText(bundle.getString(Keys.BALANCE.toString(), 
       "0.00")); 
    else 
     mybalance_value.setText("0.00"); 

    //Other onCreateView related code 
} 

@Override 
public void onNewBalanceRead(String newBalance) { 
    mybalance_value.setText(newBalance); 
} 
} 

このコードは、私の応用が期待完璧に同じように動作しますが、私はよりよいがあるかどうかを知りたいですフラグメントから新しいインテントを処理する方法は?

+0

このリンクにアクセスするには、あなたの要求に似ているhttp://stackoverflow.com/questions/17144512/pass-intent-to-my-fragment?noredirect=1&lq=1 –

答えて

-2

いいえ、いい方法はありません。フラグメントはアクティビティーより長く生存することができ、必ずしもそれらに結びついているわけではないので、新しいインテントを提供することは理にかなっていません。

ところで、あなたのコード内のいくつかのバグを持っている:)

if (actionBar.getSelectedNavigationIndex() != 1) { 

魔法の数字が悪いです!定数を使う。

if (myBalanceBundle == null) 
     myBalanceBundle = new Bundle(); 

    myBalanceBundle.putString(Keys.BALANCE.toString(), balance); 
    actionBar.setSelectedNavigationItem(1); 

は、我々はすでにnavigationitemがnullチェックを追加1

} else { 
    newBlanceListener.onNewBalanceRead(balance); 

に設定されていることを知っています。ユーザは、ナビゲーションアイテムを選択したことがないかもしれない。

+0

これは元の質問には答えません!フラグメントのonNewIntentの使い方について – developer1011

2

これは古い質問ですが、誰かがそれにぶつかる場合に私はそれに答えることができます。あなたのコードのバグを持っているすべての

まず:

あなたはActivity内部リスナーとしてあなたがそれを行う方法をFragments登録することはできません。その理由は、ActivityFragmentsがシステムによって破壊され、後で保存された状態から再作成されるためです(Recreating an Activityの文書を参照)。この場合、ActivityFragmentの新しいインスタンスが作成されますが、Fragmentをリスナーとして設定するコードは実行されないため、onNewBalanceRead()は決して呼び出されません。これはAndroidアプリケーションの非常に一般的なバグです。

ActivityからFragmentにイベントを伝えるために、私は、少なくとも2つの可能なアプローチを参照してください。an officially recommended approach for communication between Fragmentsがあり

:ベース

インターフェイス。このアプローチは、FragmentまたはActivityのいずれかで実装されたコールバックインターフェイスを使用するという点で今のやり方と似ていますが、その欠点は密接な結合とたくさんの醜いコードです。

イベントバスは、ベース:

より良いアプローチ(私見)は、イベントバスを利用することです - 「スレーブに対し、(あなたのケースでActivity)「マスター・コンポーネント」の記事「更新」イベントバスにイベントをコンポーネント "(あなたの場合はFragment)は、onStart()のイベントバスに自身を登録して(onStop()の登録を解除します)、これらのイベントを受信します。これは、通信するコンポーネント間の結合を追加しない、よりクリーンなアプローチです。

私のすべてのプロジェクトで、Green Robot's EventBusを使用していますが、その部分を非常にお薦めできません。

0

少なくとも一つの選択肢があります:Activity.onNewIntent documentationから:

活動は常に新しい意図を受信する前に一時停止されますので、あなたはonResumeに数えることができる()は、このメソッドの後に呼び出されます。

getIntent()は依然として元のインテントを返します。 setIntent(Intent)を使用して、この新しいIntentに更新することができます。

FragmentActivity.onNewIntent documentationですが、私は上記のステートメントと矛盾するとは思わないです。私のテストではこの前提が確認されていますが、Fragment.onResumeFragmentActivity.onResumeの後に呼び出されることを前提にしています。そう(Kotlinの例)

override fun onNewIntent(intent: Intent?) { 
    setIntent(intent) 
    super.onNewIntent(intent) 
} 

そしてFragment.onResumeに私が活動ドン」そう

override fun onResume() { 
    super.onResume() 
    doStuff(activity.intent) 
} 

この方法のような新しい意思を扱うことができるように活動してテントを更新し、このIに基づいて、それがどのような断片であるかを知る必要はありません。

関連する問題