6

Android 4.1ActionBar提供了有用的导航模式作为列表或选项卡。我正在使用 aSpinnerAdapter从三个片段中进行选择以显示在视图中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;
    }
}
4

1 回答 1

4

你可以这样做:

  1. 当您基于后退按钮选择导航项时,创建一个布尔值来跟踪:

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

    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;
    }
    
于 2012-10-17T23:13:48.330 回答