跟踪活动中的碎片?

时间:2015-06-23 06:17:53

标签: android android-fragments

我有3个片段(A,B和C)的活动。片段A已添加到活动onCreate中,但也未添加到backstack

此活动的导航流程可以是:

A - > B - > C,或 A - > ç

在片段B或C上按回或navigateUp应返回上一个片段。

将片段添加到活动的代码是:

private void switchFragment(Fragment fragment, boolean addToBackStack) {
    FragmentTransaction ft = getFragmentManager().beginTransaction();
    ft.replace(R.id.container_fragments, fragment, fragment.getClass().getSimpleName());

    if (addToBackStack) {
        ft.addToBackStack(null);
    }

    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
    ft.commit();

    currentFragment = fragment;
}

获取当前片段的代码是:

private Fragment getCurrentFragment(){
    FragmentManager fm = getFragmentManager();

    if (fm.getBackStackEntryCount() == 0)
        return null;

    String tag = fm.getBackStackEntryAt(fm.getBackStackEntryCount() - 1).getName();

    return getFragmentManager().findFragmentByTag(tag);
}

我覆盖onBackPressedonNavigateUp如下:

@Override
public void onBackPressed() {
    super.onBackPressed();

    currentFragment = getCurrentFragment();
    if (currentFragment == null) {
        currentFragment = fragmentA;
    }

    setHeader();
}

@Override
public boolean onNavigateUp() {
    if (currentFragment == fragmentA) {
        return super.onNavigateUp();
    }

    else {
        getFragmentManager().popBackStack();
        currentFragment = getCurrentFragment();

        if (currentFragment == null) {
            currentFragment = fragmentA;
        }

        setHeader();
        return true;
    }
}

setHeader是一种根据显示的当前片段更改活动标题文本的方法。

如果我从A导航到C并向后导航,则上述工作正常。但是,从A到B导航到C并向后导航不起作用。当从C返回到B时,代码认为它已经在A上(显示A的标题文本),但是正在显示片段B.

以上不是处理后台堆的正确方法吗?我做错了什么?

2 个答案:

答案 0 :(得分:0)

此代码表现良好,您可以查看一次。     public void pushFragments(String tag,Fragment fragment,boolean shouldAnimate,boolean shouldAdd){

    if (shouldAdd)
        mStacks.get(tag).push(fragment);
    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction ft = manager.beginTransaction();
    if (shouldAnimate){
        ft.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left);
        //Toast.makeText(getApplicationContext(), "Hi", Toast.LENGTH_SHORT).show();
        }else{
            ft.setCustomAnimations(0, 0);
        }

    ft.replace(R.id.frame_container, fragment);
    ft.commit();
//  Toast.makeText(getApplicationContext(), "+"+ mStacks.get(mCurrentNavigatorMenu).size(), Toast.LENGTH_LONG).show();
}

public void popFragments() {
    /*
     * Select the second last fragment in current tab's stack.. which will
     * be shown after the fragment transaction given below
     */
    //Toast.makeText(getApplicationContext(), ""+ mStacks.get(mCurrentNavigatorMenu).size(), Toast.LENGTH_LONG).show();
    Fragment fragment = mStacks.get(mCurrentNavigatorMenu).elementAt(mStacks.get(mCurrentNavigatorMenu).size() - 2);

    /* pop current fragment from stack.. */
    mStacks.get(mCurrentNavigatorMenu).pop();

    /*
     * We have the target fragment in hand.. Just show it.. Show a standard
     * navigation animation
     */
    FragmentManager manager = getSupportFragmentManager();
    FragmentTransaction ft = manager.beginTransaction();
    ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);

    ft.replace(R.id.frame_container, fragment);
    ft.commit();
}


@Override
public void onBackPressed() {
    if (((BaseFragment) mStacks.get(mCurrentNavigatorMenu).lastElement())
            .onBackPressed() == false) {
        /*
         * top fragment in current tab doesn't handles back press, we can do
         * our thing, which is
         * 
         * if current tab has only one fragment in stack, ie first fragment
         * is showing for this tab. finish the activity else pop to previous
         * fragment in stack for the same tab
         */
        if (mStacks.get(mCurrentNavigatorMenu).size() == 1) {
            super.onBackPressed();
            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_HOME);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);// or call finish..
        } else {
            popFragments(); 
        }
    } else {
        // do nothing.. fragment already handled back button press.
        Toast.makeText(getApplicationContext(), "Nothing", Toast.LENGTH_LONG).show();
    }
}

答案 1 :(得分:0)

以上代码适用于导航。我删除了setHeader方法并将其移到此处:

    final FragmentManager fm = getFragmentManager();
    fm.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            Fragment fr = fm.findFragmentById(R.id.container_fragments);
            if(fr!=null){
                currentFragment = fr;
                setTitle();
            }
        }
    });

这样我知道当前正在显示哪个片段并设置标题 相应