如何在遍历Fragment后台堆栈时刷新ActionBar导航项?

时间:2012-10-17 20:53:22

标签: android android-fragments android-actionbar

Android 4.1 ActionBar提供了一种有用的导航模式作为列表或标签。我使用SpinnerAdapter从三个片段中进行选择,以便在视图android.R.id.content中显示。 然后onNavigationItemSelected()侦听器将每个片段膨胀到视图,并使用FragmentTransaction.addToBackStack(null)将其添加到后台堆栈。

这一切都按照宣传的方式工作,但我不知道如何更新ActionBar以反映当前的后台堆栈。使用ActionBar.setSelectedNavigationItem(position)工作但也会触发新的OnNavigationListener(),这也会创建另一个FragmentTransaction(不是我想要的效果)。代码如下所示,以便澄清。任何有关解决方案的帮助都表示赞赏。


public class CalcActivity extends Activity {
private String[] mTag = {"calc", "timer", "usage"};
private ActionBar actionBar;

/** An array of strings to populate dropdown list */
String[] actions = new String[] {
    "Calculator",
    "Timer",
    "Usage"
};

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    this.actionBar = getActionBar();

    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
    // may not have room for Title in actionbar
    actionBar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);

    actionBar.setListNavigationCallbacks(
    // Specify a SpinnerAdapter to populate the dropdown list.
    new ArrayAdapter<String>(
        actionBar.getThemedContext(),
        android.R.layout.simple_list_item_1,
        android.R.id.text1,
        actions),
    // Provide a listener to be called when an item is selected.
    new NavigationListener()
    );      
}

public class NavigationListener implements ActionBar.OnNavigationListener {
    private Fragment mFragment;
    private int firstTime = 0;

    public boolean onNavigationItemSelected(int itemPos, long itemId) {
        mFragment = getFragmentManager().findFragmentByTag(mTag[itemPos]);

        if (mFragment == null) {
            switch (itemPos) {
            case 0:
                mFragment = new CalcFragment();
                break;
            case 1:
                mFragment = new TimerFragment();
                break;
            case 2:
                mFragment = new UsageFragment();
                break;
            default:
                return false;
            }               
            mFragment.setRetainInstance(true);
        }

        FragmentTransaction ft = getFragmentManager().beginTransaction();
        if (firstTime == 0) {
            firstTime++;
            ft.add(android.R.id.content, mFragment, mTag[itemPos]);
        } else {
            ft.replace(android.R.id.content, mFragment, mTag[itemPos]);
            ft.addToBackStack(null);
        }
        ft.commit();

        Toast.makeText(getBaseContext(), "You selected : " + 
                actions[itemPos], Toast.LENGTH_SHORT).show();

        return true;
    }       
}

public static class CalcFragment extends Fragment {             
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_calc, container, false);
    return v;
    }   
}

public static class TimerFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_timer, container, false);
    return v;
    }   
}

public static class UsageFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_usage, container, false);
    return v;
    }
}

1 个答案:

答案 0 :(得分:4)

你可以这样做:

  1. 创建一个布尔值,以便在您根据后退按钮选择导航项时进行跟踪:

    private boolean mListIsNavigatingBack = false;
    
  2. 覆盖onBackPressed,在覆盖中检查backstack是否有项目,如果有,请自行处理,如果没有调用超类:

    public void onBackPressed() {
        if(getFragmentManager().getBackStackEntryCount() > 0){
            mListIsNavigatingBack = true;
    
            //You need to get the previous index in the backstack through some means
            //possibly by storing it in a stack
            int previousNavigationItem = ???;
    
            getActionBar().setSelectedNavigationItem(previousNavigationItem);
        }
        else{
            super.onBackPressed();
        }
    }
    
  3. 在NavigationListener内部,处理mListIsNavigatingBack状态,手动弹出后台堆栈并取消设置状态:

    if(mListIsNavigatingBack){
        if(fm.getBackStackEntryCount() > 0){
            fm.popBackStack();
        }
        mListIsNavigatingBack = false;
    }