点击 >> 按钮之后
现在Language下选择一个想要添加的语言。
点击OK就可以了。
这样就添加好了,这里再附一个values命名对应的国家目录,可供参考,我也是百度出来的。
Arabic, Egypt (ar_EG) -----------------------------阿拉伯语,埃及
Arabic, Israel (ar_IL) -------------------------------阿拉伯语,以色列
Bulgarian, Bulgaria (bg_BG) ---------------------保加利亚语,保加利亚
Catalan, Spain (ca_ES) ---------------------------加泰隆语,西班牙
Czech, Czech Republic (cs_CZ) -----------------捷克语,捷克共和国
Danish, Denmark(da_DK) ------------------------丹麦语,丹麦
German, Austria (de_AT) -------------------------德语,奥地利
German, Switzerland (de_CH) -------------------德语,瑞士
German, Germany (de_DE) ----------------------德语,德国
German, Liechtenstein (de_LI) ------------------德语,列支敦士登的
Greek, Greece (el_GR) ----------------------------希腊语,希腊
English, Australia (en_AU) -------------------------英语,澳大利亚
English, Canada (en_CA) --------------------------英语,加拿大
English, Britain (en_GB) ----------------------------英语,英国
English, Ireland (en_IE) -----------------------------英语,爱尔兰
English, India (en_IN) --------------------------------英语,印度
English, New Zealand (en_NZ) ---------------------英语,新西兰
English, Singapore(en_SG) --------------------------英语,新加坡
English, US (en_US) -----------------------------------英语,美国
English, Zimbabwe (en_ZA) --------------------------英语,津巴布韦
Spanish (es_ES) ----------------------------------------西班牙
Spanish, US (es_US) -----------------------------------西班牙语,美国
Finnish, Finland (fi_FI) ---------------------------------芬兰语,芬兰
French, Belgium (fr_BE) -------------------------------法语,比利时
French, Canada (fr_CA) -------------------------------法语,加拿大
French, Switzerland (fr_CH) --------------------------法语,瑞士
French, France (fr_FR) --------------------------------法语,法国
Hebrew, Israel (he_IL) ---------------------------------希伯来语,以色列
Hindi, India (hi_IN) -------------------------------------印地语,印度
Croatian, Croatia (hr_HR) ----------------------------克罗地亚语,克罗地亚
Hungarian, Hungary (hu_HU) ------------------------匈牙利语,匈牙利
Indonesian, Indonesia (id_ID) ------------------------印尼语,印尼
Italian, Switzerland (it_CH) ----------------------------意大利语,瑞士
Italian, Italy (it_IT) ---------------------------------------意大利语,意大利
Japanese (ja_JP) ----------------------------------------日语
Korean (ko_KR) ------------------------------------------朝鲜语
Lithuanian, Lithuania (lt_LT) --------------------------立陶宛语,立陶宛
Latvian, Latvia (lv_LV) ---------------------------------拉托维亚语,拉托维亚
Norwegian-Bokmol, Norway(nb_NO) ---------------挪威语,挪威
Dutch, Belgium (nl_BE) --------------------------------荷兰语,比利时
Dutch, Netherlands (nl_NL) ---------------------------荷兰语,荷兰
Polish (pl_PL) -------------------------------------------波兰
Portuguese, Brazil (pt_BR) ---------------------------葡萄牙语,巴西
Portuguese, Portugal (pt_PT) ------------------------葡萄牙语,葡萄牙
Romanian, Romania (ro_RO) ------------------------罗马尼亚语,罗马尼亚
Russian (ru_RU) ----------------------------------------俄语
Slovak, Slovakia (sk_SK) ------------------------------斯洛伐克语,斯洛伐克
Slovenian, Slovenia (sl_SI) ---------------------------斯洛文尼亚语,斯洛文尼亚
Serbian (sr_RS) ----------------------------------------塞尔维亚语
Swedish, Sweden (sv_SE) ----------------------------瑞典语,瑞典
Thai, Thailand (th_TH) --------------------------------泰语,泰国
Tagalog, Philippines (tl_PH) --------------------------菲律宾语,菲律宾
Turkish, Turkey (tr_TR) -------------------------------土耳其语,土耳其
Ukrainian, Ukraine (uk_UA) --------------------------联合王国
Vietnamese, Vietnam (vi_VN) -----------------------越南语,越南
Chinese, PRC (zh_CN)--------------------------------中文,中国
Chinese, Taiwan (zh_rTW)-----------------------------中文,台湾
values-加上后面括号里面的值就可以了。不保证一定正确,不正确的可以参考刚才AS手动添加语言文件夹步骤。
这里只是一个简单的教程而已,所以我会把刚才新建的values-zh删掉,因为已经有默认的values表示中文了。
多语言因为要注意一个点,当你添加了一个文字资源时,对应的语言文件夹里都要添加,比如我在values的strings.xml中添加了一个你好,那么就要在values-en的strings.xml中添加一个Hello,同样也要在values-zh-rTW下的strings.xml中添加你好。你好的简体和繁体都是一样的。
下面修改一下activity_main.xml的布局
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”
xmlns:app=“http://schemas.android.com/apk/res-auto”
xmlns:tools=“http://schemas.android.com/tools”
android:layout_width=“match_parent”
android:layout_height=“match_parent”
android:fitsSystemWindows=“true”
android:orientation=“vertical”
tools:context=“.MainActivity”>
<androidx.appcompat.widget.Toolbar
android:id=“@+id/toolbar”
android:layout_width=“match_parent”
android:layout_height=“?attr/actionBarSize”
android:background=“?attr/colorPrimary”>
<TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_gravity=“center”
android:text=“@string/multi_language”
android:textColor=“#000”
android:textSize=“18sp” />
<ImageView
android:id=“@+id/iv_setting”
android:layout_width=“24dp”
android:layout_height=“24dp”
android:layout_gravity=“end”
android:layout_marginRight=“12dp”
android:src=“@drawable/ic_settings” />
</androidx.appcompat.widget.Toolbar>
<LinearLayout
android:layout_width=“match_parent”
android:layout_height=“match_parent”
android:gravity=“center”
android:orientation=“vertical”>
<TextView
android:id=“@+id/tv_sys_language”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“@string/system_language”
android:textColor=“#000”
android:textSize=“16sp” />
<TextView
android:id=“@+id/tv_cur_language”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_marginTop=“12dp”
android:text=“@string/current_language”
android:textColor=“#000”
android:textSize=“16sp” />
<TextView
android:id=“@+id/tv_other_pages”
android:layout_width=“match_parent”
android:layout_height=“?attr/actionBarSize”
android:layout_marginTop=“50dp”
android:background=“#FFF”
android:gravity=“center”
android:text=“@string/other_pages”
android:textColor=“#000”
android:textSize=“16sp” />
然后修改activity_other.xml的布局
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”
xmlns:app=“http://schemas.android.com/apk/res-auto”
xmlns:tools=“http://schemas.android.com/tools”
android:layout_width=“match_parent”
android:layout_height=“match_parent”
android:fitsSystemWindows=“true”
tools:context=“.OtherActivity”>
<androidx.appcompat.widget.Toolbar
android:id=“@+id/toolbar”
app:navigationIcon=“@drawable/ic_return”
android:layout_width=“match_parent”
android:layout_height=“?attr/actionBarSize”
android:background=“?attr/colorPrimary”>
<TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_gravity=“center”
android:text=“@string/other_pages”
android:textColor=“#000”
android:textSize=“18sp” />
</androidx.appcompat.widget.Toolbar>
最后修改activity_setting.xml的布局
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”
xmlns:app=“http://schemas.android.com/apk/res-auto”
xmlns:tools=“http://schemas.android.com/tools”
android:layout_width=“match_parent”
android:layout_height=“match_parent”
android:orientation=“vertical”
android:fitsSystemWindows=“true”
tools:context=“.SettingActivity”>
<androidx.appcompat.widget.Toolbar
android:id=“@+id/toolbar”
android:layout_width=“match_parent”
app:navigationIcon=“@drawable/ic_return”
android:layout_height=“?attr/actionBarSize”
android:background=“?attr/colorPrimary”>
<TextView
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_gravity=“center”
android:text=“@string/setting”
android:textColor=“#000”
android:textSize=“18sp” />
</androidx.appcompat.widget.Toolbar>
<LinearLayout
android:orientation=“vertical”
android:layout_width=“match_parent”
android:layout_height=“match_parent”>
<TextView
android:id=“@+id/tv_choose_lang”
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:layout_marginBottom=“8dp”
android:layout_marginStart=“16dp”
android:layout_marginTop=“24dp”
android:text=“@string/choose_lang”
android:textColor=“#7A7A7A”
android:textSize=“12sp” />
<RelativeLayout
android:id=“@+id/lay_system”
android:layout_width=“match_parent”
android:layout_height=“44dp”
android:background=“#FFF”
android:gravity=“center_vertical”>
<TextView
android:layout_width=“wrap_content”
android:layout_height=“match_parent”
android:layout_marginStart=“16dp”
android:gravity=“center”
android:text=“@string/system_lang”
android:textColor=“#4A4A4A”
android:textSize=“14sp” />
<ImageView
android:id=“@+id/iv_system”
android:layout_width=“20dp”
android:layout_height=“20dp”
android:layout_alignParentEnd=“true”
android:layout_centerVertical=“true”
android:layout_marginEnd=“24dp”
android:padding=“2dp”
android:src=“@drawable/ic_check” />
<RelativeLayout
android:id=“@+id/lay_chinese”
android:layout_width=“match_parent”
android:layout_height=“48dp”
android:layout_marginTop=“1dp”
android:background=“#FFF”
android:gravity=“center_vertical”>
<TextView
android:layout_width=“wrap_content”
android:layout_height=“match_parent”
android:layout_marginStart=“16dp”
android:gravity=“center”
android:text=“@string/chinese”
android:textColor=“#4A4A4A”
android:textSize=“14sp” />
<ImageView
android:id=“@+id/iv_chinese”
android:layout_width=“20dp”
android:layout_height=“20dp”
android:layout_alignParentEnd=“true”
android:layout_centerVertical=“true”
android:layout_marginEnd=“24dp”
android:padding=“2dp”
android:src=“@drawable/ic_check”
android:visibility=“gone” />
<RelativeLayout
android:id=“@+id/lay_english”
android:layout_width=“match_parent”
android:layout_height=“48dp”
android:layout_marginTop=“1dp”
android:background=“#FFF”
android:gravity=“center_vertical”>
<TextView
android:layout_width=“wrap_content”
android:layout_height=“match_parent”
android:layout_marginStart=“16dp”
android:gravity=“center”
android:text=“@string/english”
android:textColor=“#4A4A4A”
android:textSize=“14sp” />
<ImageView
android:id=“@+id/iv_english”
android:layout_width=“20dp”
android:layout_height=“20dp”
android:layout_alignParentEnd=“true”
android:layout_centerVertical=“true”
android:layout_marginEnd=“24dp”
android:padding=“2dp”
android:src=“@drawable/ic_check”
android:visibility=“gone” />
<RelativeLayout
android:id=“@+id/lay_traditional_chinese”
android:layout_width=“match_parent”
android:layout_height=“48dp”
android:layout_marginTop=“1dp”
android:background=“#FFF”
android:gravity=“center_vertical”>
<TextView
android:layout_width=“wrap_content”
android:layout_height=“match_parent”
android:layout_marginStart=“16dp”
android:gravity=“center”
android:text=“@string/traditional_chinese”
android:textColor=“#4A4A4A”
android:textSize=“14sp” />
<ImageView
android:id=“@+id/iv_traditional_chinese”
android:layout_width=“20dp”
android:layout_height=“20dp”
android:layout_alignParentEnd=“true”
android:layout_centerVertical=“true”
android:layout_marginEnd=“24dp”
android:padding=“2dp”
android:src=“@drawable/ic_check”
android:visibility=“gone” />
三个Activity的页面都写好了,下面改动一下代码。
首先是MainActivity。在MainActivity中去继承BaseActivity,然后实现控件的点击事件监听。
package com.llw.language;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.os.LocaleList;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.Locale;
/**
-
主页面
-
@author llw
*/
public class MainActivity extends BaseActivity implements View.OnClickListener {
private TextView tvSystemLanguage;//系统语言
private TextView tvCurrentLanguage;//当前语言
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView imageView = findViewById(R.id.iv_setting);
TextView tvOtherPage = findViewById(R.id.tv_other_pages);
tvSystemLanguage = findViewById(R.id.tv_sys_language);
tvCurrentLanguage = findViewById(R.id.tv_cur_language);
imageView.setOnClickListener(this);
tvOtherPage.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.iv_setting://进入设置页面
goToActivity(SettingActivity.class);
break;
case R.id.tv_other_pages://进入其他页面
goToActivity(OtherActivity.class);
break;
default:
break;
}
}
/**
-
跳转页面
-
@param clazz 目标Activity
*/
private void goToActivity(Class<?> clazz) {
startActivity(new Intent(this,clazz));
}
}
再来看。OtherActivity。
package com.llw.language;
import androidx.appcompat.widget.Toolbar;
import android.os.Bundle;
/**
-
其他页面
-
@author llw
*/
public class OtherActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_other);
Toolbar toolbar = findViewById(R.id.toolbar);
Back(toolbar);
}
}
最后是SettingActivity。
package com.llw.language;
import androidx.appcompat.widget.Toolbar;
import android.os.Bundle;
/**
-
设置页面
-
@author llw
*/
public class SettingActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting);
Toolbar toolbar = findViewById(R.id.toolbar);
Back(toolbar);
}
}
下面你就可以运行了,无论你是运行在虚拟器还是手机,都可以。AS中默认下载的模拟器打开之后是英文的,因此刚来可以测试一下这个APP是否会适配Android系统语言。
OK,已经适配了,那么接下来用自己的手机来运行一下,看是不是会显示中文。(如果自己的手机默认是英文的语言,我只能说你是个人才)
点击跳转其他页面或者设置页面也都是中文的,我这里就不一一截图了。
刚才不是还有一个繁体的吗?那么将自己手机的语言改成繁体,再打开这个APP,看看会怎么样。更改Android系统需要,通常在手机的设置里面,然后在设置里面找到有系统相关的选项。再找到语言相关的选项。之后选择语言和地区,然后切换一下语言看看。
我现在已经切换到繁体了,然后再打开APP。
呐,没骗你吧。骗倒是没骗我,不过,这难道就是多语言吗?只是配置了多个语言文件就可以了吗?
那当然不是,你要知道这种方式适合一般的用户使用,是没有问题的。而某些用户为了装个逼,明明系统语言是中文的,但是它要求你APP要有英文、日文、法文等一些语言。这个时候你再根据系统来设置就不合适了,因为不都不认识,多了改变资源文件只是在适配Android系统中改动的语言,而对于App中修改语言还要进一步改进才行。
刚才是通过改变系统语言进而改变APP页面,下面是不改变系统语言也要改变APP语言。
做过Android应用开发的相信对Application是不陌生的,常规的是通过写一个自定义的Applictaion,比如BaseApplication,然后继承自Application。然后在BaseApplication中进行一些应用的初始化操作之类。而既然是改动APP的语言,那么肯定是和这个Applictaion是有关系的。
下面新建一个utils包,包下新建一个SPUtils类。代码如下:
package com.llw.language.utils;
import android.content.Context;
import android.content.SharedPreferences;
import java.util.Locale;
/**
-
语言缓存工具类
-
@author llw
*/
public class SPUtils {
private final String SP_NAME = “language_setting”;//缓存名称
private final String TAG_LANGUAGE = “language_select”;
private static volatile SPUtils instance;
private final SharedPreferences mSharedPreferences;
private Locale systemCurrentLocal = Locale.CHINESE;//系统当前本地语言为中文 初始值
public SPUtils(Context context) {
//通过上下文获取本地缓存
mSharedPreferences = context.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
}
/**
-
设置语言
-
@param select 选中的语言项
*/
public void setLanguage(int select) {
//缓存编辑者
SharedPreferences.Editor editor = mSharedPreferences.edit();
//放入保存的语言项
editor.putInt(TAG_LANGUAGE, select);
//提交 之后 缓存语言项保存完毕
editor.commit();
}
/**
-
获取语言
-
@return 从缓存中根据缓存名或者缓存值,如果没有,则返回默认值0
*/
public int getLanguage() {
return mSharedPreferences.getInt(TAG_LANGUAGE, 0);
}
/**
-
设置系统当前本地
-
@param local 本地对象
*/
public void setSystemCurrentLocal(Locale local) {
systemCurrentLocal = local;
}
/**
-
获取系统当前本地
-
@return 系统当前本地
*/
public Locale getSystemCurrentLocal() {
return systemCurrentLocal;
}
/**
-
获取实例
-
@param context 上下文参数
-
@return SPUtils实例对象
*/
public static SPUtils getInstance(Context context) {
if (instance == null) {//等于空则重新创建实例,不为空则直接返回
synchronized (SPUtils.class) {//增加一个同步锁,如果已经有了实例则跳出
if (instance == null) {
//创建新的对象
instance = new SPUtils(context);
}
}
}
return instance;
}
}
下面是另一个工具类LocalManageUtils,代码如下:
package com.llw.language.utils;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.os.LocaleList;
import android.util.Log;
import com.llw.language.R;
import java.util.Locale;
/**
-
本地管理工具类
-
@author llw
*/
public class LocalManageUtils {
private static final String TAG = “LocalManage”;
/**
-
获取系统的 locale对象
-
@param context 上下文参数
-
@return locale对象
*/
public static Locale getSystemLocal(Context context) {
return SPUtils.getInstance(context).getSystemCurrentLocal();
}
/**
-
获取当前APP使用的语言
-
@param context 上下文参数
-
@return 语言类型描述
*/
public static String getSelectLanguage(Context context) {
//根据缓存中的语言返回当前设置的语言类型文字
switch (SPUtils.getInstance(context).getLanguage()) {
case 0:
return context.getString(R.string.system_lang);
case 1:
return context.getString(R.string.chinese);
case 2:
return context.getString(R.string.english);
case 3:
return context.getString(R.string.traditional_chinese);
default:
return context.getString(R.string.chinese);
}
}
/**
-
获取选择的语言设置
-
@param context 上下文参数
-
@return locale
*/
public static Locale getSelectLanguageLocal(Context context) {
switch (SPUtils.getInstance(context).getLanguage()) {
case 0:
return getSystemLocal(context);//系统语言
case 1:
return Locale.CHINESE;//中文
case 2:
return Locale.ENGLISH;//英文
case 3:
return Locale.TRADITIONAL_CHINESE;//中文繁体
default:
return Locale.CHINESE;//中文
}
}
/**
-
设置选中的语言
-
@param context 上下文参数
-
@param select 选中的语言项
*/
public static void setSelectLanguage(Context context, int select) {
//放入缓存中
SPUtils.getInstance(context).setLanguage(select);
//设置APP语言
setAppLanguage(context);
}
/**
-
设置App语言
-
@param context
*/
public static void setAppLanguage(Context context) {
//通过应用全局上下文获取资源对象
Resources resources = context.getApplicationContext().getResources();
//获取资源配置对象
Configuration config = resources.getConfiguration();
//获取系统本地对象
Locale locale = getSelectLanguageLocal(context);
//配置本地资源
config.setLocale(locale);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//Android7.0及以上
//获取本地语言列表
LocaleList localeList = new LocaleList(locale);
//设置默认语言列表
LocaleList.setDefault(localeList);
//设置语言环境列表
config.setLocales(localeList);
//创建配置系统的上下文参数
context.getApplicationContext().createConfigurationContext(config);
//设置默认语言
Locale.setDefault(locale);
}
//更新资源配置
resources.updateConfiguration(config, resources.getDisplayMetrics());
}
/**
-
设置本地语言
-
@param context 上下文参数
-
@return 设置后的对象
*/
public static Context setLocale(Context context) {
return updateResource(context, getSelectLanguageLocal(context));
}
/**
-
更新资源
-
@param context 上下文参数
-
@param locale 本地语言
-
@return
*/
private static Context updateResource(Context context, Locale locale) {
//设置默认语言
Locale.setDefault(locale);
//通过上下文获取资源对象
Resources resources = context.getResources();
//资源配置对象
Configuration config = new Configuration(resources.getConfiguration());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {//Android4.2及以上
//设置语言
config.setLocale(locale);
//获取设置之后的上下文参数
context = context.createConfigurationContext(config);
} else {
//配置语言
config.setLocale(locale);
//更新资源配置
resources.updateConfiguration(config, resources.getDisplayMetrics());
}
return context;
}
/**
-
设置系统当前语言
-
@param context
*/
public static void setSystemCurrentLanguage(Context context) {
Locale locale;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//Android7.0及以上
locale = LocaleList.getDefault().get(0);
} else {
locale = Locale.getDefault();
}
Log.d(TAG, locale.getLanguage());
//设置应用当前本地语言
SPUtils.getInstance(context).setSystemCurrentLocal(locale);
}
/**
-
更改应用配置
-
@param context 上下文参数
*/
public static void onConfigurationChanged(Context context) {
setSystemCurrentLanguage(context);
setLocale(context);
setAppLanguage(context);
}
}
里面的方法都是有注释的,也都是比较简单的方法,这里就不过多的解释了。
上面的LocalManageUtils中最多的参数是Context,上下文参数平时通常是在Activity、Service、Fragment等一些组件中使用,那你有没有想过这些组件中的Context是怎么来的,常规的都是这些组件的生命周期,你突然说Context是怎么来的?这就触及到我的知识盲区了。首先Activity的这个上下文参数是怎么来的,这里可以重写一个方法。
比如在BaseActivity中,通过重写attachBaseContext方法,对Actiivty附加基础上下文,里面使用父类的attachBaseContext方法。
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
}
那么它的父类是谁呢?很显然之前我继承了AppCompatActivity。那么肯定就是这个里面,那么再进去里面看看。
你会发现怎么这里面又调用了父类的attachBaseContext方法,那就还得再找下去,你会发现AppCompatActivity最终继承自Activity(中间省略若干个Activity),子类继承父类,一般来说都是为了拓展,那么为什么要拓展,而不是在原来的基础上改呢?因为要适配。都知道Android的版本有很多,很多古老的版本现在都见不到了,但是Google仍然要去适配,因为那些低版本的Android系统现在不一定还在手机上,但是Android系统又不是只有手机的产品,还有其他的,比如TV、智能穿戴,这些设备的Android版本通常不高,因为更多的是做定制的。所以Android版本级别越低得到的权限就越多,改起来越简单。
然后你会发现Activity继承自ContextThemeWrapper,同样在调用了父类ContextThemeWrapper的attachBaseContext。
而ContextThemeWrapper又继承了ContextWrapper,它里面也是调用父类ContextWrapper的attachBaseContext。
在ContextWrapper这里终于不再调用父类了。累坏了吧,喝口水歇歇。
在这里可以看看有哪些类使用了attachBaseContext。哪些类就能拿到上下文参数。
你有没有发现,这里并没有看到Fragment,因为Fragment是依附在Actiivty上的。而ContextWrapper 继承了底层的Context,Context本身是一个抽象类,所以ContextWrapper 就是它的实现类,在这个实现类中,获取上下文,然后通过层层的继承和封装就传到了Activity。
嗯!有理有据,不过你说了半天这个Context的意义在哪里呢?它的意义就在于它可以改变应用和页面的资源配置。而当页面的资源配置发生改变时,就会调用attachBaseContext方法重新配置上下文,以达到切换资源配置的目的,就像切换语言这样。这么说你是否有一些明白呢?
刚才说了这么多理论的东西,手痒难耐了吧,来动手实践一下吧。之前在BaseActivity中重写了attachBaseContext,然后里面调用父类的attachBaseContext,然后传了一个上下文参数进去,而我就是要对这个参数动手脚。
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(LocalManageUtils.setLocale(newBase));
}
这里调用了LocalManageUtils的setLocale方法。
/**
-
设置本地语言
-
@param context 上下文参数
-
@return 设置后的对象
*/
public static Context setLocale(Context context) {
return updateResource(context, getSelectLanguageLocal(context));
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
最后
最后这里放上我这段时间复习的资料,这个资料也是偶然一位朋友分享给我的,里面包含了腾讯、字节跳动、阿里、百度2019-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。
还有 高级架构技术进阶脑图、高级进阶架构资料 帮助大家学习提升进阶,也可以分享给身边好友一起学习。
一起互勉~
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
aseContext,然后传了一个上下文参数进去,而我就是要对这个参数动手脚。
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(LocalManageUtils.setLocale(newBase));
}
这里调用了LocalManageUtils的setLocale方法。
/**
-
设置本地语言
-
@param context 上下文参数
-
@return 设置后的对象
*/
public static Context setLocale(Context context) {
return updateResource(context, getSelectLanguageLocal(context));
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-NQJKAiIQ-1712769043937)]
[外链图片转存中…(img-alJSi5MI-1712769043938)]
[外链图片转存中…(img-H1j6ynnB-1712769043938)]
[外链图片转存中…(img-tgwFiqHB-1712769043938)]
[外链图片转存中…(img-Quatf3zo-1712769043938)]
[外链图片转存中…(img-zRY4A3q3-1712769043939)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-ERjbAVMq-1712769043939)]
最后
最后这里放上我这段时间复习的资料,这个资料也是偶然一位朋友分享给我的,里面包含了腾讯、字节跳动、阿里、百度2019-2021面试真题解析,并且把每个技术点整理成了视频和PDF(知识脉络 + 诸多细节)。
还有 高级架构技术进阶脑图、高级进阶架构资料 帮助大家学习提升进阶,也可以分享给身边好友一起学习。
[外链图片转存中…(img-UWLZSUzJ-1712769043939)]
[外链图片转存中…(img-OAUR7LiR-1712769043939)]
一起互勉~
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-w9z24KiC-1712769043940)]