web-dev-qa-db-de.com

Android: Anwendungsweite Einstellung der Schriftgröße

Ist es möglich, eine anwendungsweite Einstellung für die Schriftgröße vorzunehmen, die von allen Ansichten verwendet wird, in denen Text angezeigt wird? Ich möchte dem Benutzer eine Voreinstellung geben, mit der der gesamte Text in der App skaliert werden kann.

Android erlaubt ausdrücklich die Verwendung der Maßeinheit "sp" für skalierbaren Text, es gibt jedoch keine Möglichkeit, die "Voreinstellung für die Schriftgröße des Benutzers" global festzulegen.

Das Durchlaufen aller Ansichten zur Aktivitätsinstanziierung ist eigentlich keine Option ;-)

22
ge0rg

Hier ist, wie ich es für meine App gemacht habe. In wenigen Worten - in Activity.onCreate() erhalten Sie die Ressourcen-ID des Stils mit bestimmten Schriftgrößen und wenden diesen Stil auf das Thema der Aktivität an. Dann können Sie mit den Einstellungen zwischen diesen Sets wechseln.

Zunächst deklarieren Sie in values ​​/ attrs.xml Attribute für eine Reihe von Schriftgrößen:

<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>

Dann deklarieren Sie in values ​​/ styles.xml einige Sätze von Schriftgrößen:

<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>

Dann in onCreate() Methode jeder Aktivität hinzufügen:

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

wobei Preferences eine Fassade zum SharedPreferences Objekt ist:

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();
    }
}

und FontStyle ist:

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;
    }
}

Und FontStyle.values() wird als Element für Spinner in Ihrer PreferencesActivity verwendet. So sieht meins aus:

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());
}
}

Und schließlich können Sie Ihre Einstellungen für die Schriftgröße verwenden:

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

Oder ich bevorzuge die Verwendung von Stilen, in values ​​/ styles.xml hinzufügen:

<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>

Und Sie können es auf diese Weise verwenden:

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

Ich hoffe, meine Antwort wird Ihnen helfen.

48
mixel

Ja es ist möglich. Dazu müssen Sie:

  1. Deklarieren Sie Ihre eigene Klasse, die TextView erweitert
  2. Verwenden Sie in all Ihren Dialogen/Aktivitäten nur diese

Mögen:

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;
    }
}

Und jetzt können Sie, wo immer Sie sind, alle Textgrößen in allen Textansichten, die nur aufgerufen werden, global auf 20 ändern:

SimpleTextView.setGlobalTextSize(20);
5
barmaley

Hier ist die Idee, aus der Hüfte heraus zu fotografieren (keine benutzerdefinierte TextView-Implementierung erforderlich)

  1. Deklarieren Sie eine Eigenschaft wie UNIVERSAL_FONT_SIZE mit der Idee, dass sie in den Einstellungen geändert werden kann, aber zwischen App-Aufrufen beibehalten wird
  2. In der onCreate-Methode jeder Ihrer Aktivitäten wird der Wert dieser Eigenschaft abgerufen und als Feld gespeichert
  3. Stellen Sie Ihren Code so ein, dass er für jede in der Textgröße veränderbare Komponente verwendet wird
  4. Nichts hindert Sie tatsächlich daran, mehrere Eigenschaften wie BUTTONS_TXT_SIZE, TEXT_SIZE, LIST_TXT_SIZE usw. zu erstellen und dann eine Logik zu verwenden, die beispielsweise die prozentuale Textzunahme berücksichtigt und die richtigen Größen für jeden Steuerelementtyp berechnet (da Sie möglicherweise unterschiedliche Größen für verschiedene Steuerelemente haben) )

Sagen Sie in diesem Sinne, Sie möchten dafür sorgen, dass dies dynamisch funktioniert? Erstellen Sie eine einfache Klasse (z. B. TextSetter) mit einer internen Liste und drei Methoden: add, remove und setSize

  1. Identifizieren Sie in Activity#onCreate jedes Steuerelement, das Sie anpassen möchten, und verwenden Sie TextSetter#set, um es der Liste hinzuzufügen
  2. Wenn der Benutzer die Schriftgröße möglicherweise über das Menü erhöhen oder verringern möchte, führen Sie einfach TextSetter # setSize aus, in dem Sie die Liste der Steuerelemente durchlaufen, ermitteln Sie den Typ und passen Sie die Textgröße entsprechend an
1
Bostone

Für diejenigen, die Probleme beim Aufblasen von Ansichten mit benutzerdefinierten Attributen von @mixels answer haben.

Wenn Ihre Ansichten fragmentiert sind, müssen Sie FontStyle auch in onCreateView() des Fragments anwenden oder die Werte dieser Attribute im Thema der Anwendung festlegen.

Weitere Details finden Sie unter meiner Adresse hier .

0
Tomask