应用程序按导航抽屉中片段内的后退按钮退出 [英] App exits on presing back button inside fragments within navigation drawer

查看:93
本文介绍了应用程序按导航抽屉中片段内的后退按钮退出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试从子片段移动到父片段时,我的应用程序退出(它不会崩溃).LandingActivity.java是主要活动,我在其中调用片段ChannelGrid.java,后者调用片段GridMain.java.在片段GridMain应用程序退出时按了移动设备的后退按钮,而不是移至ChannelGrid.java.我向片段添加了addToBackStack("tag"),还尝试使用onKey()..我也在不同设备上测试了我的应用程序.找出其他具有相同问题的解决方案,并进行了尝试,但无济于事.

Navigation Drawer-LandingActivity.java-ChaanelGrid.java(Fragment)-GridMain.java(Fragment)

LandingActivity.java

   currentFragment = new ChaanelGrid();

                currentFragment.setArguments(args);
                frgManager = getFragmentManager();

                frgManager.beginTransaction().add(R.id.content_frame, currentFragment).addToBackStack("tag")
                        .commit();

ChaanelGrid.java

Fragment currentFragment = new GridMain();



                    FragmentManager frgManager;
                    frgManager = getFragmentManager();
                    frgManager.beginTransaction().add(R.id.content_frame, currentFragment).addToBackStack("GridMain")
                            .commit()

GridMain.java(我也尝试过不使用onKey()方法,但是没有用)

rootView.setOnKeyListener(new View.OnKeyListener() {


   @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK)
            {
                Fragment currentFragment = new ChaanelGrid();


                FragmentManager frgManager;
                frgManager = getFragmentManager();
                frgManager.beginTransaction().replace(R.id.content_frame, currentFragment)
                        .commit();
                return true;
            }

logcat详细

   10-31 21:46:57.954  24452-24452/D/ActivityThread﹕ ACT-AM_ON_PAUSE_CALLED ActivityRecord{41eb8b98 token=android.os.BinderProxy@41bb9828 {xyz/xyz..activity.LandingActivity_}}
10-31 21:46:57.971  24452-24452/ D/ActivityThread﹕ ACT-PAUSE_ACTIVITY_FINISHING handled : 0 / android.os.BinderProxy@41bb9828
10-31 21:46:58.007  24452-24452/ V/InputMethodManager﹕ focusOut: android.widget.GridView@41f06f40 mServedView=android.widget.GridView@41f06f40 winFocus=false
10-31 21:46:58.297  24452-24452/ I/SurfaceTextureClient﹕ [0x5143bc58] frames:44, duration:1.002000, fps:43.883736
10-31 21:46:58.350  24452-24452/ D/OpenGLRenderer﹕ Flushing caches (mode 0)
10-31 21:46:58.432  24452-24452/ D/OpenGLRenderer﹕ Flushing caches (mode 0)
10-31 21:46:58.753  24452-24452/ D/OpenGLRenderer﹕ Flushing caches (mode 0)
10-31 21:46:58.754  24452-24452/ D/OpenGLRenderer﹕ Flushing caches (mode 0)
10-31 21:46:58.755  24452-24452/ D/OpenGLRenderer﹕ Flushing caches (mode 2)
10-31 21:46:58.879  24452-24452/ D/ActivityThread﹕ ACT-DESTROY_ACTIVITY handled : 1 / android.os.BinderProxy@41bb9828

我尝试在LandingActivity.java中添加以下内容

@Override

public void onBackPressed() {
    FragmentManager frgManager;
    frgManager = getFragmentManager();

    Fragment fragment = fragmentManager.findFragmentByTag("GridMain");
    if (fragment != null) {
        GridMain gridMain = (GridMain) fragment;
        if (!gridMain.onBackPressed()) {
            super.onBackPressed();
        }
    }
    else {
        super.onBackPressed();
    }
}

并随后在GridMain.java中

   protected boolean onBackPressed() {
        FragmentManager frgManager;
        frgManager = getFragmentManager();
        frgManager.popBackStack();
        return true;
    }

使用日志,我检查了LandingActivity.java的onBackPressed()是否正在被调用,但输出仍然相同.

解决方案

这是我通常处理后退"按钮的方式:

// "State Machine" variables: to indicate which is the active Fragment.
private static boolean isHelpShown = false;
protected static boolean isInfoShown = false;
protected static boolean isMainShown = false;
private static boolean isViewShown = false;

// Used to switch between Fragments.
private static enum Fragments
{
    MAIN,
    VIEW,
    HELP,
    INFO
}

@Override
public final void onBackPressed()
{
    if (isMainShown)
    {
        // We're in the MAIN Fragment.
        finish();
    }
    else
    {
        // We're somewhere else, reload the MAIN Fragment.
        showFragment(Fragments.MAIN);
    }
}

private final void showFragment(final Fragments FragmentType)
{
    isViewShown = false;
    isHelpShown = false;
    isInfoShown = false;
    isMainShown = false;

    final FragmentTransaction ft =
        getSupportFragmentManager().beginTransaction();

    /*
    Replace whatever is in the fragment_container view with this
    fragment, and add the transaction to the back stack so the user can
    navigate back.
    */
    switch(FragmentType)
    {
        case HELP:
        {
            ft.replace(R.id.frgMaster, new FRG_Help());
            isHelpShown = true;
            break;
        }
        case INFO:
        {
            ft.replace(R.id.frgMaster, new FRG_Info());
            isInfoShown = true;
            break;
        }
        case VIEW:
        {
            ft.replace(R.id.frgMaster, new FRG_View());
            isViewShown = true;
            break;
        }
        case MAIN:
        {
            ft.replace(R.id.frgMaster, new FRG_Main());
            isMainShown = true;
            break;
        }
    }

    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);

    // Finalize the transaction...
    ft.commit();

    getSupportFragmentManager().executePendingTransactions();
}

如您所见,出于我的需要,我只会在我们进入MAIN Fragment(我退出)时或不在(当我回到MAIN Fragment:回到另一个MAIN Fragment,然后退出时)处理.

您可以在onBackPressed方法中添加更多检查,以检查您是否在另一个Fragment中,并相应地加载另一个.

My app exits when i try to move from child fragment to parent fragment(it doesn't crashes).Here LandingActivity.java is main activity in which I am calling fragment ChannelGrid.java which calls fragment GridMain.java.When i presses back button of mobile in fragment GridMain app exits rather than moving to ChannelGrid.java.I have added addToBackStack("tag") to fragments and also tried using onKey()..I tested my app on different devices also..I checked out other solutions with same issue and tried them but nothing works..

Navigation Drawer-LandingActivity.java-ChaanelGrid.java(Fragment)-GridMain.java(Fragment)

LandingActivity.java

   currentFragment = new ChaanelGrid();

                currentFragment.setArguments(args);
                frgManager = getFragmentManager();

                frgManager.beginTransaction().add(R.id.content_frame, currentFragment).addToBackStack("tag")
                        .commit();

ChaanelGrid.java

Fragment currentFragment = new GridMain();



                    FragmentManager frgManager;
                    frgManager = getFragmentManager();
                    frgManager.beginTransaction().add(R.id.content_frame, currentFragment).addToBackStack("GridMain")
                            .commit()

GridMain.java(i tried without onKey() method also but didn't worked)

rootView.setOnKeyListener(new View.OnKeyListener() {


   @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK)
            {
                Fragment currentFragment = new ChaanelGrid();


                FragmentManager frgManager;
                frgManager = getFragmentManager();
                frgManager.beginTransaction().replace(R.id.content_frame, currentFragment)
                        .commit();
                return true;
            }

logcat verbose

   10-31 21:46:57.954  24452-24452/D/ActivityThread﹕ ACT-AM_ON_PAUSE_CALLED ActivityRecord{41eb8b98 token=android.os.BinderProxy@41bb9828 {xyz/xyz..activity.LandingActivity_}}
10-31 21:46:57.971  24452-24452/ D/ActivityThread﹕ ACT-PAUSE_ACTIVITY_FINISHING handled : 0 / android.os.BinderProxy@41bb9828
10-31 21:46:58.007  24452-24452/ V/InputMethodManager﹕ focusOut: android.widget.GridView@41f06f40 mServedView=android.widget.GridView@41f06f40 winFocus=false
10-31 21:46:58.297  24452-24452/ I/SurfaceTextureClient﹕ [0x5143bc58] frames:44, duration:1.002000, fps:43.883736
10-31 21:46:58.350  24452-24452/ D/OpenGLRenderer﹕ Flushing caches (mode 0)
10-31 21:46:58.432  24452-24452/ D/OpenGLRenderer﹕ Flushing caches (mode 0)
10-31 21:46:58.753  24452-24452/ D/OpenGLRenderer﹕ Flushing caches (mode 0)
10-31 21:46:58.754  24452-24452/ D/OpenGLRenderer﹕ Flushing caches (mode 0)
10-31 21:46:58.755  24452-24452/ D/OpenGLRenderer﹕ Flushing caches (mode 2)
10-31 21:46:58.879  24452-24452/ D/ActivityThread﹕ ACT-DESTROY_ACTIVITY handled : 1 / android.os.BinderProxy@41bb9828

I tried adding following in LandingActivity.java

@Override

public void onBackPressed() {
    FragmentManager frgManager;
    frgManager = getFragmentManager();

    Fragment fragment = fragmentManager.findFragmentByTag("GridMain");
    if (fragment != null) {
        GridMain gridMain = (GridMain) fragment;
        if (!gridMain.onBackPressed()) {
            super.onBackPressed();
        }
    }
    else {
        super.onBackPressed();
    }
}

and following in GridMain.java

   protected boolean onBackPressed() {
        FragmentManager frgManager;
        frgManager = getFragmentManager();
        frgManager.popBackStack();
        return true;
    }

Using Log i checked tht onBackPressed() of LandingActivity.java is being called but still the same output..

解决方案

This is how I normally handle the Back Button:

// "State Machine" variables: to indicate which is the active Fragment.
private static boolean isHelpShown = false;
protected static boolean isInfoShown = false;
protected static boolean isMainShown = false;
private static boolean isViewShown = false;

// Used to switch between Fragments.
private static enum Fragments
{
    MAIN,
    VIEW,
    HELP,
    INFO
}

@Override
public final void onBackPressed()
{
    if (isMainShown)
    {
        // We're in the MAIN Fragment.
        finish();
    }
    else
    {
        // We're somewhere else, reload the MAIN Fragment.
        showFragment(Fragments.MAIN);
    }
}

private final void showFragment(final Fragments FragmentType)
{
    isViewShown = false;
    isHelpShown = false;
    isInfoShown = false;
    isMainShown = false;

    final FragmentTransaction ft =
        getSupportFragmentManager().beginTransaction();

    /*
    Replace whatever is in the fragment_container view with this
    fragment, and add the transaction to the back stack so the user can
    navigate back.
    */
    switch(FragmentType)
    {
        case HELP:
        {
            ft.replace(R.id.frgMaster, new FRG_Help());
            isHelpShown = true;
            break;
        }
        case INFO:
        {
            ft.replace(R.id.frgMaster, new FRG_Info());
            isInfoShown = true;
            break;
        }
        case VIEW:
        {
            ft.replace(R.id.frgMaster, new FRG_View());
            isViewShown = true;
            break;
        }
        case MAIN:
        {
            ft.replace(R.id.frgMaster, new FRG_Main());
            isMainShown = true;
            break;
        }
    }

    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);

    // Finalize the transaction...
    ft.commit();

    getSupportFragmentManager().executePendingTransactions();
}

As you can see, for my needs I only handle when we're in the MAIN Fragment (I quit) or when we aren't (I go back to the MAIN Fragment: another Back press and it quits).

You can add more checks in the onBackPressed method to check if you are in another Fragment and load another one, accordingly.

这篇关于应用程序按导航抽屉中片段内的后退按钮退出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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