android list 替换元素_Android App内动态替换语言

背景:

剪映出海,产品需要在不同语言环境下验收UI,手机切换语言效率较低,因此需要在App内支持动态替换语言提高产品/设计同学验收效率,这套方案亦可作为App内设置语言方案。

替换语言意味着什么?

我们知道Context里是能够通过​getResources​函数获取当前上下文对应的资源,然后就可以通过getString获得对应的文案。

而getString会返回​getText(id).toString();​

//android.content.res.Resources#getText(int)

@NonNull public CharSequence getText(@StringRes int id) throws NotFoundException {

CharSequence res = mResourcesImpl.getAssets().getResourceText(id);

if (res != null) {

return res;

}

throw new NotFoundException("String resource ID #0x"

+ Integer.toHexString(id));

}

可以看到getText又是通过getAssets()去拿的资源。而ResourcesImpl的mAssets字段又是在实例化时赋值。

public ResourcesImpl(@NonNull AssetManager assets, @Nullable DisplayMetrics metrics, @Nullable Configuration config, @NonNull DisplayAdjustments displayAdjustments) {

mAssets = assets;

mMetrics.setToDefaults();

mDisplayAdjustments = displayAdjustments;

mConfiguration.setToDefaults();

updateConfiguration(config, metrics, displayAdjustments.getCompatibilityInfo());

}

public void updateConfiguration(Configuration config, DisplayMetrics metrics,

CompatibilityInfo compat) {

//...

mAssets.setConfiguration(mConfiguration.mcc, mConfiguration.mnc,

adjustLanguageTag(mConfiguration.getLocales().get(0).toLanguageTag()),

mConfiguration.orientation,

mConfiguration.touchscreen,

mConfiguration.densityDpi, mConfiguration.keyboard,

keyboardHidden, mConfiguration.navigation, width, height,

mConfiguration.smallestScreenWidthDp,

mConfiguration.screenWidthDp, mConfiguration.screenHeightDp,

mConfiguration.screenLayout, mConfiguration.uiMode,

mConfiguration.colorMode, Build.VERSION.RESOURCES_SDK_INT);

//...

}

从上面可以看到,通过Resources去获取对应语系文案的配置应该就是在mConfiguration.getLocales()里配置的了,所以我们如果能修改掉Configuration.mLocaleList字段那应该就可以实现替换语言的功能了。

所以动态替换语言也就意味着动态替换掉context.resources.configuration.mLocaleList的值。

替换语言只需要对与界面相关的Context相关,也就是Activity(ContextThemeWapper)的Context,Fragment用的也是Activity的Context。当然因为程序内部某些地方会用到​applicationContext.getResources().getString()​,因此applicationContext的Configuration的Locale配置我们也是需要修改的。

PS:一个应用里面有多少个Context?答案是:Num Of Activity + Num Of Service + 1(Application),

四大组件中ContentProvider&BroadcastReceiver并不继承于Context,他们只是使用到了Context来使用上下文环境。

0d6df3fec7d5

Context相关类

那么我们需要在什么时机去替换Context的内部资源配置?

我们需要Application&Activity在​attachBaseContext​,还有Fragment在​attachActivity​时也需要修改Activity的Configuration。

在程序内部的Application/BaseActivity/BaseFragment的​attachBaseContext​/​onAttach​执行了以下方法,在运行时语言就会全局替换了。

//com.vega.launcher.ScaffoldApplication

override fun attachBaseContext(base: Context) {

su

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值