如何防止系统字体大小更改对 android 应用程序的影响?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21546805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 04:43:58  来源:igfitidea点击:

how to prevent system font-size changing effects to android application?

androidandroid-fonts

提问by james

I recently finished developing my android application. I used sp (Scaled pixels) for all textSize. The problem is when i adjusted the system font-size, my application's font-sizes are changing. I can use dp (Device independent pixels) but it will take too long to maintain my application.

我最近完成了我的 android 应用程序的开发。我对所有 textSize 都使用了 sp(缩放像素)。问题是当我调整系统字体大小时,我的应用程序的字体大小正在改变。我可以使用 dp(设备独立像素),但维护我的应用程序需要很长时间。

I referenced text size from this.

我从这里引用了文本大小。

Is there a way to prevent system font-size changing effects to my application ?

有没有办法防止系统字体大小更改对我的应用程序产生影响?

回答by Adam S

If you require your text to remain the same size, you'll have to use dp.

如果您要求文本保持相同大小,则必须使用dp.

To quote the documentation:

引用文档

An spis the same base unit, but is scaled by the user's preferred text size(it's a scale-independent pixel), so you should use this measurement unit when defining text size (but never for layout sizes).

Ansp是相同的基本单位,但按用户首选的文本大小(它是一个与比例无关的像素)进行缩放,因此在定义文本大小时应使用此度量单位(但绝不能用于布局大小)。

Emphasis mine.

强调我的。

So you're seeing the expected behaviour for using spas your units for text size.

因此,您将看到sp用作文本大小单位的预期行为。

I don't understand what you mean about using dp taking too long to maintain your app - as far as I can tell, it'll exactly be the same amount of effort? (perhaps less, though it'll likely make it less usable for users with poor eyesight)

我不明白您说使用 dp 花费太长时间来维护您的应用程序是什么意思-据我所知,这将是完全相同的工作量?(也许更少,但对于视力不佳的用户来说,它可能不太有用)

回答by welshk91

I recently ran into this problem as well. Our UI didn't scale well on phones with limited screen dimensions and changing the entire UI on the off chance a user set's their Accessibility Options to "Huge" seemed silly.

我最近也遇到了这个问题。我们的 UI 在屏幕尺寸有限的手机上无法很好地扩展,并且如果用户将其辅助功能选项设置为“巨大”,则更改整个 UI 似乎很愚蠢。

I found this questionon StackOverflow to be most helpful.

我发现StackOverflow 上的这个问题最有帮助。

What I did was put the following code below in my BaseActivity (an Activity class that all my activities extend from)

我所做的是将以下代码放在我的 BaseActivity(我的所有活动都从其扩展的 Activity 类)中

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

And called it right after my super.onCreate()like so

并在我super.onCreate()喜欢 之后立即调用它

adjustFontScale(getResources().getConfiguration());

What this code does is identify if the user set their font scale in Accessibility Settings to something greater than 1.30f (1.30f is "Large" on The Note 5, but probably varies a bit from device-to-device). If the user set their font too large ("Extra Large", "Huge"...), we scale the application only to "Large".

此代码的作用是识别用户是否在辅助功能设置中将字体比例设置为大于 1.30f(1.30f 在 Note 5 上是“大”,但可能因设备而异)。如果用户将他们的字体设置得太大(“超大”、“超大”...),我们只将应用程序缩放到“大”。

This allows your app to scale to a user's preferences (to a degree) without distorting your UI. Hopefully this will help others. Good luck scaling!

这允许您的应用程序根据用户的偏好(在一定程度上)进行缩放,而不会扭曲您的 UI。希望这会帮助其他人。祝你缩放好运!

Other Tips

其他提示

If you want certain layouts to scale with your fonts (say...a RelativeLayoutthat you use as a backdrop against your fonts), you can set their width/height with sp instead of the classic dp. When a user changes their font size, the layout will change accordingly with the fonts in your application. Nice little trick.

如果您希望某些布局与您的字体一起缩放(例如……RelativeLayout您用作字体背景的一个),您可以使用 sp 而不是经典的 dp 设置它们的宽度/高度。当用户改变他们的字体大小时,布局将随着应用程序中的字体而相应地改变。不错的小技巧。

回答by diogenesgg

None of the previous answers worked for me, on Android 8.1 (API 27). Here's what worked: Add the following code to your activity:

在 Android 8.1 (API 27) 上,以前的答案都不适合我。这是有效的:将以下代码添加到您的活动中:

Kotlin Code:

科特林代码:

override fun attachBaseContext(newBase: Context?) {
    super.attachBaseContext(newBase)
    val newOverride = Configuration(newBase?.resources?.configuration)
    newOverride.fontScale = 1.0f
    applyOverrideConfiguration(newOverride)
}

Java Code:

Java代码:

@Override
protected void attachBaseContext(Context newBase) {
    super.attachBaseContext(newBase);
    final Configuration override = new Configuration(newBase.getResources().getConfiguration());
    override.fontScale = 1.0f;
    applyOverrideConfiguration(override);
}

You don't need to change your AndroidManifest.xml.

你不需要改变你的AndroidManifest.xml.

回答by localhost

That's how we do it. In Applicationclass override onConfigurationChanged()like this. If you want different behavior for different activities - override onConfigurationChanged()in Activity.

我们就是这样做的。在Application类中像这样覆盖onConfigurationChanged()。如果您想要不同活动的不同行为 - 覆盖Activity 中的onConfigurationChanged()

Don't forget to add manifest tag android:configChanges="fontScale"since you are hadnling this configuration change yourself.

不要忘记添加清单标签android:configChanges="fontScale"因为您自己正在更改此配置。

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

In some helper class we have adjustFontScale()method.

在一些辅助类中,我们有adjustFontScale()方法。

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

WARNING!That will totally ignore Accessibility Font Scale user settings and will prevent your App fonts scaling!

警告!这将完全忽略 Accessibility Font Scale 用户设置,并会阻止您的 App 字体缩放!

回答by Maxim Saplin

That's how you do it in 2018 (Xamarin.Android/C# - same approach in other languages):

这就是你在 2018 年的做法(Xamarin.Android/C# - 其他语言中的相同方法):

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

All you need is override attachBaseContextmethod of activity and update config there.

您所需要的只是覆盖活动的attachBaseContext方法并在那里更新配置。

getBaseContext().getResources().updateConfiguration()is deprecated though there're numerous examples with this method. If you use this approach besides the IDE warning you might find some parts of your app not scaled.

getBaseContext().getResources().updateConfiguration()已被弃用,尽管此方法有很多示例。如果您在 IDE 警告之外使用此方法,您可能会发现应用程序的某些部分未缩放。

回答by Chauyan

There's another way to prevent app layout issue / font issue from the setting font size change. You can try

还有另一种方法可以防止设置字体大小更改导致应用程序布局问题/字体问题。你可以试试

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

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

where newBase is from attachBaseContext function. You need to override this callback in your Activity.

其中 newBase 来自 attachBaseContext 函数。您需要在您的活动中覆盖此回调。

But, the side effect is that if you wanna use animation (objectanimator/valueanimator), then it will cause the weird behavior.

但是,副作用是如果你想使用动画(objectanimator/valueanimator),那么它会导致奇怪的行为。

回答by Usama Saeed US

you can force to text size of your app using base activity Configuration, make all activities inherent base activity. 1.0f will force the app font size to normal ignoring system settings.

您可以使用基本活动配置强制设置应用程序的文本大小,使所有活动成为固有的基本活动。1.0f 将强制应用程序字体大小正常忽略系统设置。

public  void adjustFontScale( Configuration configuration,float scale) {

configuration.fontScale = scale;
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);

}

@Override
 protected void onCreate(@Nullable Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     adjustFontScale( getResources().getConfiguration(),1.0f);
}