簡體   English   中英

應用程序退出導航抽屜內的片段內的后退按鈕

[英]App exits on presing back button inside fragments within navigation drawer

當我嘗試從子片段移動到父片段時,我的應用程序退出(它不會崩潰).Hhere LandingActivity.java是我調用片段ChannelGrid.java的主要活動,它調用片段GridMain.java。當我按下后退按鈕時片段中的移動設備GridMain應用程序退出而不是移動到ChannelGrid.java.I已經添加了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;
    }

使用Log我檢查了LandingActivity.java的onBackPressed(),但仍然是相同的輸出..

這就是我解決它的方法..當你按下片段里面的后退按鈕onBackPressed()時你的活動方法會被調用,如果你已經聲明了那么......導航抽屜里的片段處理后退按鈕就可以這樣了。

MainActvity

     public static boolean isMainActivityShown ;
     public static boolean isFragment1Shown=false ;
     public static boolean isFragment2Shown=false ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        isMainActivityShown=true  //inside onCreate method put isMainActivityShown true
        . 
        . 
        .
        {
        Fragment currentFragment = new Fragment1();
        isMainActivityShown=false;   //when moving to fragment1 
        isFragment1Shown=true;
        frgManager = getFragmentManager();
        frgManager.beginTransaction().replace(R.id.content_frame, currentFragment)
                                        .commit();
        }
        .
        .
        }
     @Override
        public void onBackPressed() {

            if(isMainActivityShown)
            {
                finish();
            }
            else if(isFragment1Shown)
            {
               //write the code to handle back button when you are in Fragment1
            }
           else if(isFragment2Shown)
            {  //When you are in Fragment 2 pressing back button will move to fragment1
                Fragment currentFragment = new Fragment1();
                isFragment2Shown=false;
                isFragment1Shown=true;

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

            }

片段1

Fragment currentFragment = new Fragment2();
MainActivity.isFragment1Shown=false;
MainActivity.isFragment2Shown=true;
frgManager = getFragmentManager();
frgManager.beginTransaction().replace(R.id.content_frame, currentFragment)
                                    .commit();

這就是我通常處理后退按鈕的方式:

// "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片段(我退出)或者當我們不在時(我回到MAIN片段:另一個Back press並退出)。

您可以在onBackPressed方法中添加更多檢查,以檢查您是否在另一個片段中並相應地加載另一個片段。

我建議使用TAG替換片段來產生相同的結果。

簡單示例如下所示

使用TAG將片段B添加到活動中

fragmentTransaction.replace(R.id.main_fragment_container,new FragmentB(),“TAG_B”);

片段A - >片段B [onBackPressed] - >片段A覆蓋Activity文件中的onBackPressed(),其中,

//檢查片段B,你正在查看片段B.

if(getSupportFragmentManager()。findFragmentByTag(“TAG_B”)!= null){fragmentTransaction.replace(R.id.main_fragment_container,new FragmentA(),“TAG_A”);

}

我嘗試了這里建議的所有解決方案,但沒有一個適合我。 這就是我最終通過修改最高投票答案來解決它的方法:

在托管片段的活動中,聲明FragmentManager

private FragmentManager fragmentManager;

在onCreateMethod中初始化它:

public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  fragmentManager = getFragmentManager();
  ...

最后,在你的onBackPressed方法中執行以下操作:

 public void onBackPressed() {
    if(fragmentManager.getBackStackEntryCount() != 0) {
        fragmentManager.popBackStack();
        if (IS_MAIN_SHOWN) {
            finish();
        } else  {
            displayView(0);  //this is the method that changes the fragments, takes an int argument for the position of the fragment.
        }

    } else {
        super.onBackPressed();
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM