处理片段中的新内容

Mil*_*lan 16 android android-intent android-fragments

我正在编写一个使用NFC来读取存储在其上的数据的应用程序.我的应用程序使用Fragments和Fragment没有onNewIntent()方法.因为,我正在阅读的数据是通过处理NFC相关操作的单独类来完成的,我唯一需要做的就是更新Fragment中的TextView.但是,此实现也可用于将新Intent传递给Fragment.

这是我当前使用接口的实现.在收到新的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);

}
}
Run Code Online (Sandbox Code Playgroud)

这是MyBalance Fragment,其中包含需要在读取NFC时更新的TextView:

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);
}
}
Run Code Online (Sandbox Code Playgroud)

这段代码完全像我的应用程序预期的那样,但是,我想知道是否有更好的方法来处理Fragments中的新Intent?

Vas*_*liy 5

这是一个老问题,但让我回答一下,以防有人碰到它。

首先,你的代码中有一个错误:

您无法按照您的方式注册Fragments为侦听器。Activity原因是ActivityFragments可以被系统销毁,并稍后从保存的状态重新创建(请参阅有关重新创建活动的文档)。发生这种情况时,将创建 和 的新实例Activity,但将 和 设置为侦听器的Fragment代码将不会运行,因此永远不会被调用。这是 Android 应用程序中非常常见的错误。FragmentonNewBalanceRead()

为了传达从Activity到 的事件Fragment,我至少看到两种可能的方法:

基于接口:

Fragment 之间的通信有一种官方推荐的方法。这种方法与您现在所做的类似,它使用由 或 实现的回调接口FragmentActivity但其缺点是紧密耦合和大量丑陋的代码。

基于事件总线:

更好的方法(恕我直言)是利用事件总线 - “主组件”(Activity在您的情况下)将“更新”事件发布到事件总线,而“从组件”(Fragment在您的情况下)将自身注册到事件总线onStart()(取消注册)中onStop())以便接收这些事件。这是一种更简洁的方法,不会在通信组件之间添加任何耦合。

我所有的项目都使用Green Robot 的 EventBus,我强烈推荐它。


mer*_*ica -2

不,没有更好的办法了。片段的寿命比活动更长,并且不一定与它们相关,因此提供新的意图是没有意义的。

顺便说一句,您的代码中有一些错误:)

if (actionBar.getSelectedNavigationIndex() != 1) {
Run Code Online (Sandbox Code Playgroud)

魔法数字很糟糕!使用一个常数。

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

    myBalanceBundle.putString(Keys.BALANCE.toString(), balance);
    actionBar.setSelectedNavigationItem(1);
Run Code Online (Sandbox Code Playgroud)

我们已经知道 navigationitem 设置为 1

} else {
    newBlanceListener.onNewBalanceRead(balance);
Run Code Online (Sandbox Code Playgroud)

添加空检查。用户可能从未选择过导航项。