2013-03-17 83 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需要知道它拥有哪些片段。