Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing ActionBar when using fragments

In a Fragment, called within an activity I'm displaying a list of bus lines like this:

Page 1, when opening for the first time.

Then, once the user clicks on "Stations", I like to show a list of stations of course. I'm using this code:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.act_long_distance);

    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.add(R.id.f_long_distance, new LongDistanceFragment()).commit();
}

@SuppressWarnings({"UnusedDeclaration"})
public void showStationList(View view) {
    String tag = (String) view.getTag();
    if (tag != null && tag.length() > 0) {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        StationListFragment fragment = new StationListFragment(tag.split(","));
        ft.add(R.id.f_long_distance, fragment);
        // ft.replace(R.id.f_long_distance, fragment);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
        ft.addToBackStack(null);
        ft.commit();
    }
}

The XML for this activity is:

<LinearLayout
    android:id="@+id/ll_container"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    >
    <FrameLayout
        android:id="@+id/f_long_distance"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</LinearLayout>

StationListFragment is a simple ListFragment displayed on top of the other:

After clicking on the Station List button

What works well though is the ActionBar, it now properly contains the Title only.

What doesn't work is if I press back now. The Station List is hidden, but the old ActionBar is not restored:

ActionBar after coming back from List button

The docs are saying that the way to add the ActionBar is using onCreateOptionsMenu methods etc.

So, in LongDistanceFragment (the first one shown), I'm creating the bar like this:

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    Log.d(TAG, "onViewCreated");
    super.onViewCreated(view, savedInstanceState);

    setHasOptionsMenu(true);
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);

    ActionBar bar = getSupportActivity().getSupportActionBar();
    bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
    bar.setListNavigationCallbacks(new SimpleSpinnerArrayAdapter(getActivity()), this);
}

But somehow it is not restored once the user is back in that Fragment.

I think a way to recover the state of the ActionBar when rolling back the Fragment Transaction is needed.

What am I missing? Thanks for any help.

like image 817
Sebastian Roth Avatar asked Oct 19 '11 08:10

Sebastian Roth


2 Answers

If I understand your code correctly, the problem is likely within your StationListFragment.

The ActionBar is associated with the Activity itself, not a particular Fragment within it.

I'm guessing that within the StationListFragment you're modifying the ActionBar to display the "Stations" title and disable the List navigation mode. In that case, pressing the back button undoes the transaction -- effectively removing the StationListFragment -- but doesn't automagically undo any changes you might have made to the Activity's Action Bar.

What you'll need to do is override one of the state change handlers within your Station List Fragment to undo the ActionBar changes when it's removed / hidden.

A better approach would be to use a replace transaction to exchange the LongDistanceFragment with the StationListFragment (rather than adding the latter on top of the former.) Then you can add the code to configure the Action Bar to each Fragment so they set it up appropriately when they become visible (by overriding onResume) rather than trying to clean up after one's been removed.

like image 90
Reto Meier Avatar answered Oct 06 '22 19:10

Reto Meier


I was dealing with the same problem and when I revert changes to ActionBar in the onStop method of the second Fragment, it works fine.

like image 39
David Vávra Avatar answered Oct 06 '22 20:10

David Vávra