Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/224.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 反压至碎片(A、B、C)_Android_Android Fragments_Onbackpressed - Fatal编程技术网

Android 反压至碎片(A、B、C)

Android 反压至碎片(A、B、C),android,android-fragments,onbackpressed,Android,Android Fragments,Onbackpressed,我有主要活动和三个片段(一,二,三)。 所有这些片段都是基于BaseFragment的: public abstract class BaseFragment extends Fragment { private Toolbar mToolbar; private ActionBar mActionBar; @Override @CallSuper public void onAttach(Activity context) { super.onAttach(context);

我有主要活动和三个片段(一,二,三)。 所有这些片段都是基于BaseFragment的:

public abstract class BaseFragment extends Fragment {
private Toolbar mToolbar;
private ActionBar mActionBar;

@Override
@CallSuper
public void onAttach(Activity context) {
    super.onAttach(context);

    mToolbar = (Toolbar) getActivity().findViewById(R.id.toolbar);
    mActionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
    //mActionBar.setTitle(setMyTitle());
    //Log.i("BaseFragment", "onAttach = "+getBackStackCount());
    resetToolbarNavigation(getBackStackCount()!=0);
}

//protected abstract String setMyTitle();

@Override
@CallSuper
public void onDetach() {
    super.onDetach();
    Log.i("BaseFragment", "onDetach = " + (getBackStackCount() - 1));
    resetToolbarNavigation((getBackStackCount() - 1 )!= 0);
}

private int getBackStackCount() {
    int b = getActivity().getSupportFragmentManager().getBackStackEntryCount();
    Log.i("BaseFragment", "getBackStackCount = "+b);

    return b;
}

private void resetToolbarNavigation(boolean backNavigationEnabled) {
    mActionBar.setDisplayHomeAsUpEnabled(backNavigationEnabled);
    Log.i("BaseFragment", "resetToolbarNavigation");
    if (backNavigationEnabled) {
        mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.i("resetToolbarNavigation", "setNavigationOnClickListener");
                getActivity().onBackPressed();
            }
        });
    }
    else {
        ((StartPageActivity) getActivity()).initToolbar();
        ((StartPageActivity) getActivity()).syncState();
    }
}
}

但当我点击后退箭头时,我得到了豁免

09-22 19:28:13.233    5643-5643/com.test.mylist E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
        at com.test.exemple.BaseFragment$1.onClick(BaseFragment.java:56)
        at android.view.View.performClick(View.java:2485)
        at android.view.View$PerformClick.run(View.java:9080)
        at android.os.Handler.handleCallback(Handler.java:587)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:130)
        at android.app.ActivityThread.main(ActivityThread.java:3683)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:507)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
        at dalvik.system.NativeStart.main(Native Method)
在主要活动中被反压

    @Override
public void onBackPressed() {
        getSupportFragmentManager().popBackStack();
        Log.d("StartPageActivity", "onBackPressed " + getSupportFragmentManager().getBackStackEntryCount());

}

你能帮我吗?错误在哪里?我做错了什么?

以下是根据您的评论我认为正在发生的事情

  • 打开片段1,并从
    onAttach
  • 您导航到片段2,并从
    onAttach
  • 您导航到片段3,并从
    onAttach
  • 单击导航按钮,片段3将正确处理它,弹出backbackback并将您导航回片段2
    • resetToolbarNavigation(boolean)
      不是从片段2上的
      onAttach
      调用的,因为片段/活动未被销毁,并且片段从未分离
  • 您按下导航按钮,它再次被片段3处理,片段3没有启动,因此
    getActivity()
    返回
    null

  • 当显示片段时,您应该尝试设置导航侦听器。如果您正确地执行片段事务,您应该能够在
    onResume()

    中执行此操作。不知道为什么会出现这种异常,但是您使用片段的方法在设计上不是很好,可能会带来这种类型的问题。因此,我在这里给大家留下一些建议,这些建议在使用片段实现应用程序时对我很有用:

    • 单独的责任:活动应该负责它的内容,片段应该只负责片段的功能。为了实现这一点,您可以使用活动实现所需的方法使片段发布接口,然后在片段中使用它。例如,在您的代码中,您的片段与您的活动有着密切的关系。方法resetToolbarNavigation与属于该活动的视图交互,请注意,该方法没有执行任何属于片段责任的操作,因此整个方法应在该活动中实现,然后您可以在BaseFragment中发布一个接口,例如:

      //Get the instance of the activity implementation 
      private BaseFragmentActions baseFragmentActions;
      //Publish your interface with the methods your Activity will implement 
      public interface BaseFragmentActions {
          public void resetToolbarNavigation(boolean backNavigationEnabled);
      }
      
      //In your onAttach get the implementation from your activity
      @Override
      public void onAttach(Activity activity) {
          super.onAttach(activity);
      
          // This makes sure that the container activity has implemented
          // the callback interface. If not, it throws an exception
          try {
              baseFragmentActions = (BaseFragmentActions)activity;
          } catch (ClassCastException e) {
              throw new ClassCastException(activity.toString() + " must implement interface BaseFragmentActions");
          }
      }
      
    然后,在您的活动中,只需实现该方法,并在类似baseFragmentActions的片段中使用它;注意,这种方式BaseFragment不关心活动,只要求包含它的活动必须实现它需要的方法。要实现这一点,您也可以使用EventBus

    • 片段之间的事务应该始终在包含它的活动中完成。片段不应该知道/关心应该在之后加载哪个片段

    • 使用“活动知道它的片段,但片段不知道它的活动”的概念

    你可以这样做,你可以在你的片段中获得你的活动信息,但这可能会带来像这样的大麻烦


    希望它能帮助您了解未来设计的概念,并为我的英语感到抱歉

    BaseFragment中哪一行是56?getActivity().onBackPressed()
    getActivity()
    必须返回null。你确定附加了活动吗?当我打开程序时,显示的片段1会移动到片段2,然后移动到片段3。当我点击后退3->2时所有工作,但当2->1不工作时此错误。。。我只打开了片段1和片段2(2->1),效果很好。但当我有3个或更多的片段时,它就不起作用了………英语很棒!)所以我必须在中间片段中创建一个方法并在我的活动中实现这个接口?内部activity realize Override方法…..是的,例如,您的活动应该实现该接口:公共类MyActivity扩展activity实现BaseFragmentActions,然后在您的活动中重写该接口的方法,然后在您的片段中,您可以在BaseFragmentActions中访问该实现,以便您可以使用它,但是没有提到活动,这是它的好部分,你很熟悉android的结构。你能看一下吗如果你能看一下你的答案有问题