web-dev-qa-db-fra.com

comment empêcher les effets de modification de la taille de la police système sur les applications Android?

J'ai récemment fini de développer mon application Android. J'ai utilisé sp (pixels échelonnés) pour tout textSize. Le problème est que lorsque j'ai ajusté la taille de police du système, les tailles de police de mon application changent. Je peux utiliser dp (pixels indépendants du périphérique), mais la maintenance de mon application prendra trop de temps. 

J'ai référencé la taille du texte de this .

Existe-t-il un moyen d’empêcher les effets de modification de la taille de la police système sur mon application?

24
james

Si vous souhaitez que votre texte conserve la même taille, vous devrez utiliser dp.

Pour citer la documentation :

sp correspond à la même unité de base, mais est redimensionnée à la taille de texte préférée de l'utilisateur (il s'agit d'un pixel indépendant de l'échelle). Vous devez donc utiliser cette unité de mesure pour définir la taille du texte (mais jamais pour les tailles de présentation).

L'accent est à moi.

Vous voyez donc le comportement attendu pour l'utilisation de sp en tant qu'unités pour la taille du texte. 

Je ne comprends pas ce que vous entendez par l'utilisation de dp prenant trop de temps pour maintenir votre application. Autant que je sache, ce sera exactement la même quantité d'effort? (peut-être moins, même si cela le rendra probablement moins utilisable par les utilisateurs malvoyants)

34
Adam S

J'ai récemment rencontré ce problème aussi. Notre interface utilisateur ne fonctionnait pas bien sur les téléphones avec des dimensions d'écran limitées et modifier l'interface utilisateur entière à tout hasard, les options d'accessibilité de l'ensemble de leurs utilisateurs devenant "Énormes" semblait absurde.

J'ai trouvé cette question sur StackOverflow très utile.

Ce que j'ai fait a été mis le code suivant ci-dessous dans mon BaseActivity (une classe d'activité à partir de laquelle toutes mes activités s'étendent)

public void adjustFontScale(Configuration configuration) {
    if (configuration.fontScale > 1.30) {
        LogUtil.log(LogUtil.WARN, TAG, "fontScale=" + configuration.fontScale); //Custom Log class, you can use Log.w
        LogUtil.log(LogUtil.WARN, TAG, "font too big. scale down..."); //Custom Log class, you can use Log.w
        configuration.fontScale = (float) 1.30;
        DisplayMetrics metrics = getResources().getDisplayMetrics();
        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        wm.getDefaultDisplay().getMetrics(metrics);
        metrics.scaledDensity = configuration.fontScale * metrics.density;
        getBaseContext().getResources().updateConfiguration(configuration, metrics);
    }
}

Et l'a appelé juste après mon super.onCreate() comme si 

adjustFontScale(getResources().getConfiguration());

Ce code permet d’identifier si l’utilisateur définit l’échelle de police dans les paramètres d’accessibilité sur une valeur supérieure à 1.30f (1.30f est "Large" dans The Note 5, mais varie probablement un peu d’un périphérique à l’autre). Si l'utilisateur définit une police trop grande ("Extra Large", "Énorme" ...), l'application est redimensionnée uniquement en "Grand".

Cela permet à votre application d'adapter les préférences de l'utilisateur (dans une certaine mesure) sans déformer votre interface utilisateur. J'espère que cela aidera les autres. Bonne chance à l'échelle!

Autres astuces

Si vous souhaitez que certaines mises en page s'adaptent à vos polices (disons ... une RelativeLayout que vous utilisez comme arrière-plan par rapport à vos polices), vous pouvez définir leur largeur/hauteur avec sp au lieu de dp classique. Lorsqu'un utilisateur modifie sa taille de police, la mise en page change en fonction des polices de votre application. Joli petit truc.

35
welshk91

C’est comme cela que nous le faisons . Dans Application annulation de classeonConfigurationChanged ()like this . Si vous voulez un comportement différent pour différentes activités - écrasezonConfigurationChanged ( )dans l'activité.

N'oubliez pas d'ajouter la balise manifeste Android: configChanges = "fontScale" puisque vous avez modifié vous-même cette configuration.

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // In some cases modifying newConfig leads to unexpected behavior,
    // so it's better to edit new instance.
    Configuration configuration = new Configuration(newConfig);
    SystemUtils.adjustFontScale(getApplicationContext(), configuration);
}

Dans certaines classes d'assistance, nous avons la méthodeadjustFontScale ().

public static void adjustFontScale(Context context, Configuration configuration) {
    if (configuration.fontScale != 1) {
        configuration.fontScale = 1;
        DisplayMetrics metrics = context.getResources().getDisplayMetrics();
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        wm.getDefaultDisplay().getMetrics(metrics);
        metrics.scaledDensity = configuration.fontScale * metrics.density;
        context.getResources().updateConfiguration(configuration, metrics);
    }
}

ATTENTION! Cela ignorera totalement les paramètres utilisateur d’Accessibility Font Scale et empêchera la mise à l’échelle de vos polices App!

3
localhost

Voilà comment vous le ferez en 2018 (Xamarin.Android/C# - même approche dans d'autres langues):

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    protected override void OnCreate(Bundle bundle)
    {
...
    }

    protected override void AttachBaseContext(Context @base)
    {
        var configuration = new Configuration(@base.Resources.Configuration);

        configuration.FontScale = 1f;
        var config =  Application.Context.CreateConfigurationContext(configuration);

        base.AttachBaseContext(config);
    }
}

Tout ce dont vous avez besoin est d’annuler attachBaseContext méthode d’activité et d’actualiser la configuration à cet endroit.

getBaseContext (). getResources (). updateConfiguration () est obsolète bien qu'il existe de nombreux exemples avec cette méthode. Si vous utilisez cette approche en plus de l'avertissement IDE, il est possible que certaines parties de votre application ne soient pas mises à l'échelle.

1
Maxim Saplin

Il existe un autre moyen d'empêcher le problème de mise en page/de police d'application de modifier la taille de la police. Tu peux essayer 

// ignore the font scale here
final Configuration newConfiguration = new Configuration(
    newBase.getResources().getConfiguration()
);

newConfiguration.fontScale = 1.0f;
applyOverrideConfiguration(newConfiguration);

où newBase provient de la fonction attachBaseContext. Vous devez remplacer ce rappel dans votre activité. 

Mais, l’effet secondaire est que si vous voulez utiliser une animation (objectanimator/valueanimator), cela provoquera un comportement étrange.

0
Chauyan