Das Android 4.1 ActionBar
bietet einen nützlichen Navigationsmodus als Liste oder Registerkarte. Ich verwende ein SpinnerAdapter
aus drei Fragmenten auszuwählen im Hinblick android.R.id.content
angezeigt werden. Der onNavigationItemSelected()
Zuhörer aufbläst dann jedes Fragment zu der Ansicht, und fügt sie Stapel zu der Rückseite unter Verwendung von FragmentTransaction.addToBackStack(null)
.Wie aktualisiere ich das ActionBar-Navigationselement beim Durchqueren des Fragment-Back-Stacks?
Das funktioniert alles wie angekündigt, aber ich weiß nicht, wie Sie die ActionBar
aktualisieren, um den aktuellen Backstack widerzuspiegeln. Mit den ActionBar.setSelectedNavigationItem(position)
Werke, sondern löst auch eine neue OnNavigationListener()
, die auch eine andere FragmentTransaction
schafft (nicht die Wirkung ich will). Der Code wird zur Verdeutlichung unten angezeigt. Jede Hilfe mit einer Lösung wird geschätzt.
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;
}
}
Vielen Dank für Ihre Anregungen, die ich mit einem Stapel implementiert. Angesichts der zusätzlichen Komplexität und der einzigartigen UX habe ich Bedenken bezüglich dieses Entwurfsmusters. Ist es besser, AddObackStack() bei Verwendung der ActionBar-Navigation nie zu verwenden? – GregM
Die Liste Navigation macht es kompliziert. In der Regel wird der Backstack mehr zum Auslagern von Fragmenten in Ihrer aktuellen Ansicht verwendet. Daher könnte Ihr Anwendungsfall möglicherweise vereinfacht werden, indem Sie einfach das Fragment, das sich im Hintergrund befindet, erneut anfügen. –