更新片段以响应Android Navigation Drawer交互 [英] Updating a fragment in response to Android Navigation Drawer interaction

查看:82
本文介绍了更新片段以响应Android Navigation Drawer交互的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用的Android应用程序只有一个MainActivity,并且该应用程序的每个屏幕都以Fragment的形式实现.每个片段都在MainActivity中作为私有类变量实例化:

The Android app I'm working on has a single MainActivity and each screen of the app is implemented as a Fragment. Each fragment is instantiated like this in the MainActivity as a private class variable:

public class MainActivity extends Activity implements MainStateListener {

   private FragmentManager fm = getFragmentManager();
   private BrowseFragment browseFragment = BrowseFragment.newInstance();

...

只有一个片段框架"可加载每个屏幕片段.在应用中切换屏幕时,将调用以下代码以加载片段:

There is a single 'fragment frame' that loads each screen fragment. When switching screens in the app this code is called to load a fragment:

FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.frag_frame, incoming);
ft.addToBackStack(null);
ft.commit();
fm.executePendingTransactions();

每个屏幕片段都有一个侦听器,使该片段可以调用MainActivity中的各种方法:

Each screen fragment has a listener that enables the fragment to call various methods in the MainActivity:

public void onAttach(Activity activity) {
    super.onAttach(activity);
    try {
        mainStateListener = (MainStateListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement MainStateListener");
    }
}

我遇到的问题是从MainActivity中退出的导航抽屉更新片段的某个方面.导航抽屉必须更新该片段,并使用以下代码来完成该操作:

The issue I am having is updating an aspect of a fragment from a Navigation Drawer that exits in the MainActivity. The navigation drawer has to update the fragment, and it uses this code to do that:

        navigationDrawer.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                browseFragment.doSomethingOnBrowserFragment();
            }
        });

在更改方向之前,一切正常.然后,当前屏幕片段将加载良好(browseFragment).但是然后,当您单击导航抽屉导致doSomethingOnBrowserFragment()方法执行时,由于mainStateListener对象本身(附加到browserFragment中)为null,我得到了一个空指针异常.据我对Fragment生命周期的了解,该变量不应为null,因为onAttach()方法首先执行,然后设置mainStateListener变量.另外,如果我在使用mainStateListener对象的browserFragment上有一个按钮(遵循方向更改),则单击该按钮绝不会出现此空指针问题.

Things work fine when until you change the orientation. Then the current screen fragment loads fine (browseFragment). But then when you click the navigation drawer causing the doSomethingOnBrowserFragment() method to execute I get a null pointer exception due to the mainStateListener object itself (attached to in the browseFragment) being null. From what I know about the Fragment lifecycle this variable shouldn't be null because the onAttach() method executes first before anything and sets mainStateListener variable. Also if I have a button on that browserFragment that uses the mainStateListener object (following an orientation change), clicking the button never has this null pointer issue.

堆栈跟踪:

08-04 16:23:28.937  14770-14770/co.openplanit.totago E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: co.openplanit.totago, PID: 14770
    java.lang.NullPointerException
            at co.openplanit.totago.MapFragment.enableOfflineMode(MapFragment.java:489)
            at co.openplanit.totago.MainActivity.setMapMode(MainActivity.java:663)
            at co.openplanit.totago.MainActivity.itineraryMapDrawerSelectItem(MainActivity.java:610)
            at co.openplanit.totago.MainActivity.access$200(MainActivity.java:52)
            at co.openplanit.totago.MainActivity$5.onItemClick(MainActivity.java:420)
            at android.widget.AdapterView.performItemClick(AdapterView.java:299)
            at android.widget.AbsListView.performItemClick(AbsListView.java:1158)
            at android.widget.AbsListView$PerformClick.run(AbsListView.java:2957)
            at android.widget.AbsListView$3.run(AbsListView.java:3850)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:136)
            at android.app.ActivityThread.main(ActivityThread.java:5103)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:606)
            at dalvik.system.NativeStart.main(Native Method)

在我看来,问题可能是,使用Navigation Drawer实际上正在与browserFragment生命周期进行交互并导致其分离或其他原因.

It seems to me the issue may be that using the Navigation Drawer is actually interacting with the browseFragment lifecycle and causing it to detach or something.

任何有关如何解决此问题的建议将不胜感激.

Any suggestions on how to resolve this would be much appreciated.

推荐答案

保留对Fragment的引用可能会使您与对旧Fragment的引用保持不同步,在Fragment Manager为您重新创建Fragment的情况下

Keeping a reference to a Fragment might leave you out of sync with a reference to an old Fragment that is Detached in cases where the Fragment Manager recreates the Fragment for you.

解决方案是使用伪代码查找当前在frag_frame中的片段:

The solution is to find the fragment currently in frag_frame, in pseudo code:

Fragment fragment = fm.findFragmentById(R.id.frag_frame);
if(fragment instanceof BrowseFragment) {
   // do your stuff
}

这篇关于更新片段以响应Android Navigation Drawer交互的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆