Android UI 规模
Android UI scale
我知道 Android 系统提供了一种在整个系统上扩展 UI 的方法,但我想要类似的东西,但只适用于我的应用程序。假设在“设置”中,我可以选择缩放 UI,并使用滑块 UI 为我的应用程序放大或缩小我的应用程序。有什么简单的方法可以做到这一点吗?
更新:
我已经在 onCreate 中试过了:
private void setScale(float screenRatio) {
Resources resources = getResources();
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Configuration configuration = resources.getConfiguration();
configuration.densityDpi = (int) (metrics.densityDpi * screenRatio);
metrics.scaledDensity = metrics.scaledDensity * screenRatio;
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
}
但存在三个缺点:
- 我需要重启应用程序才能使更改生效
- 它只缩放视图而不缩放字体大小
- 更改不是实时可见的
这是相同的 260dpi 屏幕,但缩放 UI。
https://i.stack.imgur.com/wkzZb.png
https://i.stack.imgur.com/WF5rY.png
https://i.stack.imgur.com/GMYRA.png
https://i.stack.imgur.com/hTREN.png
Android 为您提供全面的设计定制。如果您想扩大规模并在所有设备上拥有最好的 UI
,您可以为 layout
文件夹使用不同类型的文件夹。
如文档所述,您可以为不同的设备自定义所有资源。
https://developer.android.com/guide/practices/screens_support.html
指定为 sp
的字体大小与密度无关,因此更改 densityDpi
不会影响其外观。尝试更改 Configuration.fontScale
这是字体的缩放因子,相对于基本密度缩放。
这就是我找到的解决方案,这里是一个如何实施它的工作示例:
https://github.com/thelong1EU/ScaleUI
1.创建一个使用自定义 Configuration 对象的 ContextWraper 对象
正如我所猜测的那样,这一切都与上下文对象有关。第一步是创建一个包含所需修改的 ContextWraper 对象。您可以从此处更改语言环境和所有其他限定符或设备属性。请在此处查看完整列表:
https://developer.android.com/reference/android/content/res/Configuration.html#lfields
public class ScaledContextWrapper extends ContextWrapper {
public ScaledContextWrapper(Context base) {
super(base);
}
@SuppressWarnings("deprecation")
public static ScaledContextWrapper wrap(Context context) {
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
DisplayMetrics metrics = resources.getDisplayMetrics();
configuration.densityDpi = (int) (metrics.densityDpi * sScaleRatio);
configuration.fontScale = sScaleRatio;
if (SDK_INT > 17) {
context = context.createConfigurationContext(configuration);
} else {
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
}
return new ScaledContextWrapper(context);
}
}
2。设置要进行修改的新上下文
如果你想改变整个Activity的比例,你需要覆盖attachBaseContext()并传递修改后的Context对象:
@Override
protected void attachBaseContext(Context newBase) {
Context context = ScaledContextWrapper.wrap(newBase);
super.attachBaseContext(context);
}
如果您只想更改一个片段甚至一个视图的比例,您需要使用使用修改后的 Context 构造的 LayoutInflater 对象。这是缩放片段的示例:
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
Context scaledContext = ScaledContextWrapper.wrap(getActivity());
LayoutInflater scaledInflater = LayoutInflater.from(scaledContext);
return scaledInflater.inflate(R.layout.fragment_layout, container, false);
}
我知道 Android 系统提供了一种在整个系统上扩展 UI 的方法,但我想要类似的东西,但只适用于我的应用程序。假设在“设置”中,我可以选择缩放 UI,并使用滑块 UI 为我的应用程序放大或缩小我的应用程序。有什么简单的方法可以做到这一点吗?
更新:
我已经在 onCreate 中试过了:
private void setScale(float screenRatio) {
Resources resources = getResources();
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
Configuration configuration = resources.getConfiguration();
configuration.densityDpi = (int) (metrics.densityDpi * screenRatio);
metrics.scaledDensity = metrics.scaledDensity * screenRatio;
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
}
但存在三个缺点:
- 我需要重启应用程序才能使更改生效
- 它只缩放视图而不缩放字体大小
- 更改不是实时可见的
这是相同的 260dpi 屏幕,但缩放 UI。
https://i.stack.imgur.com/wkzZb.png
https://i.stack.imgur.com/WF5rY.png
https://i.stack.imgur.com/GMYRA.png
https://i.stack.imgur.com/hTREN.png
Android 为您提供全面的设计定制。如果您想扩大规模并在所有设备上拥有最好的 UI
,您可以为 layout
文件夹使用不同类型的文件夹。
如文档所述,您可以为不同的设备自定义所有资源。 https://developer.android.com/guide/practices/screens_support.html
指定为 sp
的字体大小与密度无关,因此更改 densityDpi
不会影响其外观。尝试更改 Configuration.fontScale
这是字体的缩放因子,相对于基本密度缩放。
这就是我找到的解决方案,这里是一个如何实施它的工作示例: https://github.com/thelong1EU/ScaleUI
1.创建一个使用自定义 Configuration 对象的 ContextWraper 对象
正如我所猜测的那样,这一切都与上下文对象有关。第一步是创建一个包含所需修改的 ContextWraper 对象。您可以从此处更改语言环境和所有其他限定符或设备属性。请在此处查看完整列表: https://developer.android.com/reference/android/content/res/Configuration.html#lfields
public class ScaledContextWrapper extends ContextWrapper {
public ScaledContextWrapper(Context base) {
super(base);
}
@SuppressWarnings("deprecation")
public static ScaledContextWrapper wrap(Context context) {
Resources resources = context.getResources();
Configuration configuration = resources.getConfiguration();
DisplayMetrics metrics = resources.getDisplayMetrics();
configuration.densityDpi = (int) (metrics.densityDpi * sScaleRatio);
configuration.fontScale = sScaleRatio;
if (SDK_INT > 17) {
context = context.createConfigurationContext(configuration);
} else {
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
}
return new ScaledContextWrapper(context);
}
}
2。设置要进行修改的新上下文
如果你想改变整个Activity的比例,你需要覆盖attachBaseContext()并传递修改后的Context对象:
@Override
protected void attachBaseContext(Context newBase) {
Context context = ScaledContextWrapper.wrap(newBase);
super.attachBaseContext(context);
}
如果您只想更改一个片段甚至一个视图的比例,您需要使用使用修改后的 Context 构造的 LayoutInflater 对象。这是缩放片段的示例:
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
Context scaledContext = ScaledContextWrapper.wrap(getActivity());
LayoutInflater scaledInflater = LayoutInflater.from(scaledContext);
return scaledInflater.inflate(R.layout.fragment_layout, container, false);
}