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;
}
}
答案 0 :(得分:4)
你可以这样做:
创建一个布尔值,以便在您根据后退按钮选择导航项时进行跟踪:
private boolean mListIsNavigatingBack = false;
覆盖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();
}
}
在NavigationListener内部,处理mListIsNavigatingBack
状态,手动弹出后台堆栈并取消设置状态:
if(mListIsNavigatingBack){
if(fm.getBackStackEntryCount() > 0){
fm.popBackStack();
}
mListIsNavigatingBack = false;
}