2013-03-17 81 views
14

我在寫一個應用程序,它使用NFC讀取存儲在其上的一些數據。我的應用程序使用片段和片段不帶onNewIntent()方法。因爲我正在閱讀的數據是用我處理NFC相關操作的單獨類完成的,所以我需要做的唯一事情就是更新Fragment中的TextView。然而,這個實現也可以用來將新的Intent傳遞給片段。在片段中處理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); 

} 
} 

這是應查看mybalance片段,其具有的TextView需要每當NFC讀取進行更新:

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 – 2016-07-20 08:44:56

回答

-2

不,沒有更好的辦法。碎片可以比活動壽命更長,並且不一定與它們綁定,因此提供新的意圖是沒有意義的。

順便說一句,你有一些錯誤在你的代碼:)

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

幻數是壞的!使用一個常量。

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

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

我們已經知道,navigationitem設置爲1

} else { 
    newBlanceListener.onNewBalanceRead(balance); 

添加一個空檢查。用戶可能從未選擇過導航項目。

+0

這並不回答原來的問題!關於如何在片段中使用onNewIntent – developer1011 2016-05-15 16:57:43

2

這是一個古老的問題,但讓我回答它,以防有人碰到它。所有的

首先,你必須在你的代碼中的錯誤:

不能註冊Fragments作爲內部Activity聽衆,你做的方式。原因是ActivityFragments可能會被系統銷燬,並在以後從保存狀態重新創建(請參閱有關Recreating an Activity的文檔)。發生這種情況時,將創建ActivityFragment的新實例,但將Fragment設置爲偵聽器的代碼將不會運行,因此不會調用onNewBalanceRead()。這是Android應用程序中非常常見的錯誤。

爲了溝通的事件從ActivityFragment我看到至少有兩種可能的方法:

基於接口:

an officially recommended approach for communication between Fragments。這種方法與您現在所做的類似,它使用由FragmentActivity實現的回調接口,但其缺點是緊密耦合和許多難看的代碼。

事件基於總線:

更好的方法(恕我直言)是利用事件總線 - (你的情況Activity)「主成分」上崗「更新」事件,事件總線,而「奴隸組件「(您的情況爲Fragment)將自己註冊到onStart()中的事件總線(在onStop()中取消註冊)以接收這些事件。這是一種更清潔的方法,它不會在通信組件之間增加任何耦合。

我所有的項目都使用Green Robot's EventBus,我不能推薦它足夠高。

0

至少有一個替代辦法:Activity.onNewIntent documentation

的活動總是會接收到一個新的意圖前被暫停,因此),你可以指望的onResume(被調用此方法之後。

請注意getIntent()仍然返回原始的Intent。你可以使用setIntent(Intent)將它更新到這個新的Intent。

FragmentActivity.onNewIntent documentation是不同的,但我不認爲它與上述說法相抵觸。我還假設Fragment.onResume將在FragmentActivity.onResume之後被調用,儘管我的文檔似乎對我有點挑剔,儘管我的測試證實了這個假設。在此基礎上我更新了意圖在活動像這樣(在科特林例子)

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

而在Fragment.onResume我能勝任,像這樣

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

這樣,新的意向活動別t需要知道它擁有哪些片段。