Android: настройка размера шрифта для всего приложения - PullRequest
22 голосов
/ 02 февраля 2011

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

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

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

Ответы [ 4 ]

49 голосов
/ 26 сентября 2012

Вот как я сделал это для своего приложения. В нескольких словах - в 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" />

Надеюсь, мой ответ вам поможет.

5 голосов
/ 02 февраля 2011

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

  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);
1 голос
/ 21 апреля 2011

Съемка из бедра, вот идея, которую нужно рассмотреть (не требуется настраиваемая реализация 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, в котором вы будете циклически просматривать список элементов управления, определять, какой это тип, и настраиватьРазмер текста соответственно
0 голосов
/ 13 января 2016

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

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

Подробнее см. Мой aswer здесь .

...