Search code examples
androidandroid-actionbarandroid-orientationpreferenceactivityandroid-appcompat

ActionBar in PreferenceFragment not recalculating height and font size


Using the latest AppCompat-v21 library, I used ActionBarActivity to create and populate the PreferenceFragment. However, the ActionBar does not seem to change height and the text size when the orientation or screen size is altered. Testing this on other activities as well, this behavior only seems to be happening in PreferenceActivity (opposed to this question asked here: ActionBar capacity/overflow not changing on orientation change ).

First of all, to handle orientation changes, I added android:configChanges="keyboard|keyboardHidden|orientation|screenSize" to the Manifest. I suspect that this is the main reason for this problem, but as I mentioned earlier, this works on other Activitys.

Here are some screenshots that explain the issue:

Launched PreferenceActivity in Portrait mode:

Portrait start

Rotated to Landscape from Portrait:

rotate to landscape

Launched PreferenceActivity in Landscape mode:

landscape

Rotated to Portrait from Landscape:

rotate to portrait

Additional Information

Here is the PreferenceActivity class:

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;

public class PrefsActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        getFragmentManager().beginTransaction().replace(android.R.id.content, new PrefsFragment()).commit();
    }

}

Is this behavior a bug? If not, is there a workaround or a fix?


EDIT I

I tried using the new ToolBar widget, but no luck.

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;

public class PrefsActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_preference);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_pref);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        getFragmentManager().beginTransaction().replace(R.id.pref_frame, new PrefsFragment()).commit();
    }

}

Solution

  • android:configChanges is not recommended because orientation, keyboard are not the only causes of Activity recreation.

    So, the better approach is to remove this from the Manifest, and set setRetainInstance(true); on the Fragment class. This will bypass this destroy-and-recreate cycle of the Fragment, while refreshing the Activity.

    Since the Toolbar is included in the Activity and not the Fragment, this will refresh the Toolbar while keeping the Fragment.

    In case of Dialogs, the usage of the Fragment Lifecycle to close/reopen them will work.

    Source: http://developer.android.com/guide/topics/resources/runtime-changes.html