Android: настройка размера шрифта для всего приложения

Можно ли сделать настройку в масштабе приложения для размера шрифта, который будет использоваться всеми представлениями, отображающими текст? Я хотел бы предоставить предпочтение пользователю, который должен позволить масштабировать весь текст в приложении.

Android явно позволяет использовать единицу измерения "sp" для масштабируемого текста, однако нет никакого реального способа установить "предпочтение размера шрифта пользователя" глобальным способом.

Итерация по всем представлениям об экземплярах Activity на самом деле не вариант;-)

4 ответа

Решение

Вот как я сделал это для своего приложения. В нескольких словах - в Activity.onCreate() Вы получаете ресурсный идентификатор стиля с определенным набором размеров шрифта и применяете этот стиль к теме деятельности. Затем с активностью предпочтений вы можете переключаться между этими наборами.

Прежде всего в values ​​/attrs.xml объявляют атрибуты для набора размеров шрифта:

<declare-styleable name="FontStyle">
    <attr name="font_small" format="dimension" />
    <attr name="font_medium" format="dimension" />
    <attr name="font_large" format="dimension" />
    <attr name="font_xlarge" format="dimension" />
</declare-styleable>

Затем в values ​​/styles.xml объявите несколько наборов размеров шрифта:

<style name="FontStyle">
</style>

<style name="FontStyle.Small">
    <item name="font_small">14sp</item>
    <item name="font_medium">16sp</item>
    <item name="font_large">18sp</item>
    <item name="font_xlarge">20sp</item>
</style>

<style name="FontStyle.Medium">
    <item name="font_small">18sp</item>
    <item name="font_medium">20sp</item>
    <item name="font_large">22sp</item>
    <item name="font_xlarge">24sp</item>
</style>

<style name="FontStyle.Large">
    <item name="font_small">26sp</item>
    <item name="font_medium">28sp</item>
    <item name="font_large">30sp</item>
    <item name="font_xlarge">32sp</item>
</style>

Затем в onCreate() метод каждой деятельности добавить:

getTheme().applyStyle(new Preferences(this).getFontStyle().getResId(), true);

где Preferences это фасад для SharedPreferences объект:

public class Preferences {
    private final static String FONT_STYLE = "FONT_STYLE";

    private final Context context;

    public Preferences(Context context) {
        this.context = context;
    }

    protected SharedPreferences open() {
        return context.getSharedPreferences("prefs", Context.MODE_PRIVATE);
    }

    protected Editor edit() {
        return open().edit();
    }

    public FontStyle getFontStyle() {
        return FontStyle.valueOf(open().getString(FONT_STYLE,
            FontStyle.Medium.name()));
    }

    public void setFontStyle(FontStyle style) {
        edit().putString(FONT_STYLE, style.name()).commit();
    }
}

и FontStyle это:

public enum FontStyle {
    Small(R.style.FontStyle_Small, "Small"), 
    Medium(R.style.FontStyle_Medium, "Medium"), 
    Large(R.style.FontStyle_Large, "Large");

    private int resId;
    private String title;

    public int getResId() {
        return resId;
    }

    public String getTitle() {
        return title;
    }

    FontStyle(int resId, String title) {
        this.resId = resId;
        this.title = title;
    }
}

А также FontStyle.values() используется в качестве предметов для Spinner в вашем PreferencesActivity, Вот так выглядит моя:

public class PreferencesActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    getTheme().applyStyle(new Preferences(this).getFontStyle().getResId(), true);
    super.onCreate(savedInstanceState);

    setContentView(R.layout.preferences);

    Preferences prefs = new Preferences(this);

    Spinner fontStylesView = (Spinner) findViewById(R.id.font_styles);
    FontStylesAdapter adapter = new FontStylesAdapter(this,
            R.layout.font_styles_row, FontStyle.values());
    fontStylesView.setAdapter(adapter);

    fontStylesView.setSelection(prefs.getFontStyle().ordinal());
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.preferences, menu);
    return super.onCreateOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.menu_done:
        onMenuDone();
        finish();
        return true;
    case R.id.menu_cancel:
        finish();
        return true;
    default:
        return false;
    }
}

private void onMenuDone() {
    Preferences prefs = new Preferences(this);

    Spinner fontStylesView = (Spinner) findViewById(R.id.font_styles);
    prefs.setFontStyle((FontStyle) fontStylesView.getSelectedItem());
}
}

И, наконец, вы можете использовать настройки размера шрифта:

<TextView android:textSize="?attr/font_large" />

Или я предпочитаю использовать стили, в values ​​/styles.xml добавить:

<style name="Label" parent="@android:style/Widget.TextView">
    <item name="android:textSize">?attr/font_medium</item>
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
</style>

<style name="Label.XLarge">
    <item name="android:textSize">?attr/font_xlarge</item>
</style>

И вы можете использовать это следующим образом:

<TextView style="@style/Label.XLarge" />

Я надеюсь, что мой ответ поможет вам.

Да, это возможно. Для этого вам необходимо:

  1. Объявите свой собственный класс расширения TextView
  2. Используйте во всех ваших диалогах / действиях только это

Подобно:

public class SimpleTextView extends TextView
{
    private static final float DEFAULT_TEXT_SIZE=12.0;
    private static float textSize=DEFAULT_TEXT_SIZE;

    public SimpleTextView(Context context)
    {
        super(context);
        this.setTextSize(textSize);
    }

    public SimpleTextView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        this.setTextSize(textSize);
    }

    public SimpleTextView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        this.setTextSize(textSize);
    }

    public static void setGlobalSize(float size)
    {
        textSize=size;
    }

    public static float getGlobalSize()
    {
        return textSize;
    }
}

И теперь, где бы вы ни находились, вы можете глобально изменить все размеры текста до 20 во всех текстовых представлениях, просто позвонив:

SimpleTextView.setGlobalTextSize(20);

Для тех, у кого проблемы с раздуванием представлений с помощью пользовательских атрибутов из @mixels, ответим.

Если ваши взгляды фрагментированы, вам нужно применить FontStyle также во фрагментах onCreateView() или установите значения этих атрибутов в теме приложения.

Для более подробной информации смотрите мой ответ здесь.

Съемка с тазобедренного сустава - вот идея, которую нужно рассмотреть (пользовательская реализация TextView не требуется)

  1. Объявите свойство как UNIVERSAL_FONT_SIZE, полагая, что его можно изменить в настройках, но оно будет сохранено между вызовами приложения.
  2. В onCreate метод каждого из ваших действий получить значение этого свойства и сохранить в виде поля
  3. Сделайте так, чтобы ваш код использовал это для каждого компонента с изменяемым размером текста
  4. Ничто на самом деле не помешает вам создать несколько свойств, таких как BUTTONS_TXT_SIZE, TEXT_SIZE, LIST_TXT_SIZE и т. Д., А затем иметь логику, которая принимает, например, процент увеличения текста и рассчитывает надлежащие размеры для каждого типа элемента управления (поскольку у вас могут быть разные размеры для разных элементов управления)

Скажем так, вы хотите, чтобы это работало динамически? Создайте простой класс (скажем, TextSetter), который содержит внутренний список и имеет 3 метода: add, remove и setSize

  1. В Activity#onCreate определить каждый элемент управления, который вы хотите настроить и использовать TextSetter#set добавить его в список
  2. Когда пользователь хочет увеличить / уменьшить размер шрифта, возможно, из меню, когда вы обрабатываете это, просто выполняете TextSetter # setSize, в котором вы будете перебирать список элементов управления, определять, какой это тип шрифта, и соответствующим образом корректировать размер текста.
Другие вопросы по тегам