最近、Androidアプリケーションを開発しました。すべてのtextSizeにsp(スケーリングされたピクセル)を使用しました。システムのフォントサイズを調整すると、アプリケーションのフォントサイズが変化します。 dp(デバイスに依存しないピクセル)を使用しますが、アプリケーションを維持するには時間がかかりすぎます。
this からテキストサイズを参照しました。
システムのフォントサイズがアプリケーションに影響を与えるのを防ぐ方法はありますか?
テキストを同じサイズのままにする必要がある場合は、dp
を使用する必要があります。
ドキュメント を引用するには:
sp
は同じ基本単位ですが、ユーザーの好みのテキストサイズ(スケールに依存しないピクセル)でスケーリングされます。テキストサイズを定義するときにこの測定単位を使用する必要があります(ただし、レイアウトサイズには使用しないでください)。
強調鉱山。
そのため、sp
をテキストサイズの単位として使用する場合の予想される動作がわかります。
アプリを維持するのに時間がかかりすぎるdpの使用についてあなたが何を意味するのかわかりません-私が知る限り、それはまったく同じ労力になるでしょうか? (おそらく、それよりも少ないですが、それは目が悪いユーザーにとって使いにくくなるでしょう)
私も最近この問題に遭遇しました。私たちのUIは、画面のサイズが限られている携帯電話ではうまく拡張できず、ユーザーがアクセシビリティオプションを「巨大」に設定した場合にUI全体を変更するのはばかげているように見えました。
StackOverflowで question が最も役立つことがわかりました。
私がしたことは、以下のコードを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);
}
}
_
super.onCreate()
の直後に呼び出した
_adjustFontScale(getResources().getConfiguration());
_
このコードが行うことは、ユーザーが[アクセシビリティ設定]でフォントスケールを1.30fより大きい値に設定したかどうかを識別することです(注5では1.30fは「大」ですが、おそらくデバイスによって少し異なります)。ユーザーがフォントを大きくしすぎると( "Extra Large"、 "Huge" ...)、アプリケーションは "Large"にのみスケーリングされます。
これにより、UIを歪めることなく、アプリをユーザーの好みに合わせて(ある程度)スケーリングできます。これが他の人の助けになることを願っています。幸運のスケーリング!
その他のヒント
特定のレイアウトをフォントに合わせて拡大したい場合(たとえば、フォントに対する背景として使用するRelativeLayout
)、クラシックdpの代わりにspを使用して幅/高さを設定できます。ユーザーがフォントサイズを変更すると、アプリケーションのフォントに応じてレイアウトが変更されます。ちょっとしたトリック。
それが私たちのやり方です。 アプリケーションクラスのオーバーライドonConfigurationChanged()このように。アクティビティごとに異なる動作が必要な場合は、アクティビティのonConfigurationChanged()をオーバーライドします。
マニフェストタグを追加することを忘れないでください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);
}
一部のヘルパークラスには、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);
}
}
警告!これは、アクセシビリティフォントスケールのユーザー設定を完全に無視し、アプリフォントのスケーリングを防ぎます!
Android 8.1(API 27)では、これまでの回答はどれも機能しませんでした。機能したのは、次のコードをアクティビティに追加することです。
コトリンコード:
override fun attachBaseContext(newBase: Context?) {
super.attachBaseContext(newBase)
val newOverride = Configuration(newBase?.resources?.configuration)
newOverride.fontScale = 1.0f
applyOverrideConfiguration(newOverride)
}
Javaコード:
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
final Configuration override = new Configuration(newBase.getResources().getConfiguration());
override.fontScale = 1.0f;
applyOverrideConfiguration(override);
}
AndroidManifest.xml
を変更する必要はありません。
それが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);
}
}
必要なのは、オーバーライドattachBaseContextアクティビティのメソッドであり、そこで設定を更新するだけです。
getBaseContext()。getResources()。updateConfiguration()は推奨されませんが、このメソッドには多くの例があります。 IDE警告に加えてこのアプローチを使用すると、アプリの一部がスケーリングされない場合があります。
フォントサイズの変更によるアプリレイアウトの問題/フォントの問題を防ぐ別の方法があります。あなたが試すことができます
// ignore the font scale here
final Configuration newConfiguration = new Configuration(
newBase.getResources().getConfiguration()
);
newConfiguration.fontScale = 1.0f;
applyOverrideConfiguration(newConfiguration);
newBaseはattachBaseContext関数からのものです。アクティビティでこのコールバックをオーバーライドする必要があります。
しかし、副作用は、アニメーション(objectanimator/valueanimator)を使用する場合、奇妙な動作を引き起こすことです。