人行发布的要求,移动应用要做好对视障人士和老年人的适配,我们都知道有些做的不是很好的 app ,别说对老年人和视障人士不太友好,对普通人来讲也时常出现不易操作的情况。
我们这个年纪的人,父母其实刚好经历了从功能手机到智能手机的时代更替,很多时候父母对手机上的功能是用不明白的,即使教了很多遍他们也不是很懂。像我爸就不会用现在的银行软件转账、存款,每次都需要我帮他操作。所以呀,app 做好对老年人和视障人士的适配改造,是很有必要的。
今天先记录改造的第一个功能点,就是 app 内全局的字号更改。微信和支付宝都有相应的功能模块,大家伙可以自行去体验一下。一般 app 都不会特意去实现这样的功能,所以我也是第一次做,记录一下也给大家提供参考。
先贴一下我的效果图(因为 UI 切图还没给到,所以自己先简单搭了个界面,比较粗糙):
支付宝和微信都是通过滑动标尺来控制字体放大/缩小的倍数,我这里只提供三种尺寸的字号,所以就没有做滑动标尺,但是原理是一样的,以一个标准字号为基准,通过当前选择的倍数来重置全局的字号大小。
1、字体单位一定要使用 sp,有的朋友喜欢使用 dp 的。
2、选择完字号大小后(以中等字号为基准,选择小号则缩小 4 * 0.125 倍数,选择大号字体则放大 4*0.125 倍,根据需求来调整),点击确定后保存当前选择的倍数,并结束当前所有 Activity,重启 APP。fontSizeScale 是一个全局变量,用来保存当前选择的倍数。
/**
* 更新选择了字号之后对应的UI
* @param typeSize
*/
private void setUI(int typeSize){
switch (typeSize){
case TYPE_SMALL_SIZE:
if (!tv_small_size.isSelected()){
fontSizeScale = (float) (0 * 0.125 + 0.875);
//选中背景设置
tv_small_size.setSelected(true);
tv_middle_size.setSelected(false);
tv_big_size.setSelected(false);
//三角形气泡选择显示
v_rectangle_under_small_size.setVisibility(View.VISIBLE);
v_rectangle_under_middle_size.setVisibility(View.GONE);
v_rectangle_under_big_size.setVisibility(View.GONE);
//改变示例的展示字号
changeExampleTextSize();
}
break;
case TYPE_MIDDLE_SIZE:
if (!tv_middle_size.isSelected()){
fontSizeScale = (float) (4 * 0.125 + 0.875);
//选中背景设置
tv_small_size.setSelected(false);
tv_middle_size.setSelected(true);
tv_big_size.setSelected(false);
//三角形气泡选择显示
v_rectangle_under_small_size.setVisibility(View.GONE);
v_rectangle_under_middle_size.setVisibility(View.VISIBLE);
v_rectangle_under_big_size.setVisibility(View.GONE);
//改变示例的展示字号
changeExampleTextSize();
}
break;
case TYPE_BIG_SIZE:
if (!tv_big_size.isSelected()){
fontSizeScale = (float) (8 * 0.125 + 0.875);
//选中背景设置
tv_small_size.setSelected(false);
tv_middle_size.setSelected(false);
tv_big_size.setSelected(true);
//三角形气泡选择显示
v_rectangle_under_small_size.setVisibility(View.GONE);
v_rectangle_under_middle_size.setVisibility(View.GONE);
v_rectangle_under_big_size.setVisibility(View.VISIBLE);
//改变示例的展示字号
changeExampleTextSize();
}
break;
default:
fontSizeScale = (float) (4 * 0.125 + 0.875);
break;
}
btn_change_text_size_confirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//点击确定
SharedPreferenceUtil.getInstance().putValue(FONT_SIZE_SCALE, fontSizeScale);
AppManager.getAppManager().finishAllActivity();
Intent intent = new Intent(TextSizeSetting.this, MainActivityLoveVersion.class);
startActivity(intent);
}
});
3、重写 Activity 的 getResource() 方法,这是改变字号最关键一步,从缓存中取出字体字号的倍数,通过重写 getResource 重新设置。(设置倍数的 Activity 需要特殊处理一下,首次进入是没有缓存的倍数的,设置为 1 即可)
@Override
public Resources getResources() {
Resources res = super.getResources();
Configuration configuration = res.getConfiguration();
fontSizeScale = SharedPreferenceUtil.getInstance().getFloatValue(TextSizeSetting.FONT_SIZE_SCALE);
configuration.fontScale = fontSizeScale;
res.updateConfiguration(configuration, res.getDisplayMetrics());
return res;
}
/**
* 重新配置缩放系数
* @return
*/
@Override
public Resources getResources() {
Resources res =super.getResources();
Configuration config = res.getConfiguration();
if (SharedPreferenceUtil.getInstance().getFloatValue(TextSizeSetting.FONT_SIZE_SCALE) == 0){
config.fontScale= 1;//1 设置正常字体大小的倍数
}else {
config.fontScale= SharedPreferenceUtil.getInstance().getFloatValue(TextSizeSetting.FONT_SIZE_SCALE);
}
res.updateConfiguration(config,res.getDisplayMetrics());
return res;
}
到这里就实现了字号改变的功能了,后面还有很多无障碍适配的改造,会另外再写文章介绍。
20210809 补充更新
要让设置的字体全局生效,是需要重启 app 的,百度上可以查到,大多数是使用 getLaunchIntentForPackage()方法实现的,不过我这里试了不行,也不知道为什么,偶尔可以重启,偶尔执行了代码却没什么反应。所以我这里采用了比较笨的方法:
Intent intent = new Intent(TextSizeSetting.this, MainActivityLoveVersion.class);
startActivity(intent);
EventBus.getDefault().post(MainEventEnum.RECREATE_APP);
finish();
MainActivityLoveVersion.this.recreate();
通过全局的 activity 管理器结束掉所有 activity ,发送一条广播,并跳转到首页,首页接收广播执行 recreate() 方法,实现全局生效。