ActionBar в PreferenceFragment не пересчитывает высоту и размер шрифта
Используя последнюю библиотеку AppCompat-v21
, я использовал ActionBarActivity
для создания и заполнения PreferenceFragment
. Тем не менее, ActionBar
, похоже, не изменяет высоту и размер текста при изменении ориентации или размера экрана. Испытывая это на другие действия, это поведение, похоже, происходит только в PreferenceActivity
(в отличие от этого вопроса, заданного здесь: Емкость/переполнение ActionBar не меняется при изменении ориентации).
Прежде всего, чтобы обработать изменения ориентации, я добавил android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
в манифест. Я подозреваю, что это основная причина этой проблемы, но, как я упоминал ранее, это работает на других Activity
s.
Вот несколько скриншотов, которые объясняют проблему:
Запущен PreferenceActivity
в портретном режиме:
![Portrait start]()
Поворот в альбомный пейзаж:
![rotate to landscape]()
Запущен PreferenceActivity
в альбомном режиме:
![landscape]()
Поворот в портрет из пейзажа:
![rotate to portrait]()
Дополнительная информация
Вот класс PreferenceActivity
:
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();
}
}
Является ли это поведение ошибкой? Если нет, есть ли обходной путь или исправление?
РЕДАКТИРОВАТЬ I
Я попытался использовать новый виджет ToolBar
, но не повезло.
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();
}
}
Ответы
Ответ 1
android:configChanges
не рекомендуется, так как ориентация, клавиатура не являются единственными причинами активного отдыха.
Итак, лучший подход - удалить это из манифеста и установить setRetainInstance(true);
в классе Fragment
. Это обходит этот цикл уничтожения и воссоздания фрагмента, обновляя Activity.
Поскольку Toolbar
включен в Activity, а не в Fragment, это обновит панель инструментов, сохранив фрагмент.
В случае Dialogs использование Fragment Lifecycle для закрытия/повторного открытия будет работать.
Источник: http://developer.android.com/guide/topics/resources/runtime-changes.html
Ответ 2
Я могу предложить это решение.
Работает с системой ActionBar, с панелью инструментов Lollipop и панелью инструментов AppCompat.
public static void fixActionBar(Activity activity, View toolbar)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
if (toolbar == null)
{
int id = activity.getResources().getIdentifier("action_bar", "id", "android");
if (id != 0) toolbar = (Toolbar) activity.findViewById(id);
}
if (toolbar != null)
{
Context context = toolbar.getContext();
TypedArray typedArray = context.obtainStyledAttributes(new int[]
{android.R.attr.actionBarStyle, android.R.attr.actionBarSize});
int actionStyle = typedArray.getResourceId(0, 0);
int actionHeight = typedArray.getDimensionPixelSize(1, 0);
typedArray.recycle();
try
{
View container = (View) toolbar.getParent();
Field field = container.getClass().getDeclaredField("mHeight");
field.setAccessible(true);
field.setInt(container, actionHeight);
View overlay = (View) container.getParent();
field = overlay.getClass().getDeclaredField("mActionBarHeight");
field.setAccessible(true);
field.setInt(overlay, actionHeight);
}
catch (Exception e)
{
}
toolbar.getLayoutParams().height = actionHeight;
toolbar.setMinimumHeight(actionHeight);
typedArray = context.obtainStyledAttributes(actionStyle, new int []
{android.R.attr.titleTextStyle});
((Toolbar) toolbar).setTitleTextAppearance(context, typedArray.getResourceId(0, 0));
typedArray.recycle();
}
}
}
Вызвать этот метод из onConfigurationChanged вашей деятельности.
Ответ 3
Выполняют ли другие действия, которые вы тестировали, с объявлением android:configChanges
в манифесте?
Как вы сказали, проблема в том, что
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
не обрабатывает вращение. Это фактически останавливает активность и представления от воссоздания, заставляя представления не читать соответствующие значения после изменения конфигурации.
Учитывая тот факт, что вы используете фрагменты, я бы удалил атрибут android:configChanges
и сохранил экземпляр PrefsFragment
.