通俗易懂地讲解Android app国际化实现方式,开发需要注意的地方
来源:互联网 发布:java 广告位管理系统 编辑:程序博客网 时间:2024/06/05 03:56
国际化的实现只需要将res目录下的资源按照对应的规则命名即可,比如:
图片资源(不一定是mipmap,也可以是drawable)只需要命名相同,字符资源id相同。
zh-rCN表示中国,zh-rTW表示台湾,更多国家的名称缩写可以参考 http://www.cnblogs.com/linlf03/p/3680454.html
布局文件:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <ImageView android:id="@+id/iv_main_img" android:layout_width="32dp" android:layout_height="32dp" android:scaleType="centerCrop"/> <TextView android:id="@+id/tv_main_str" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:textSize="18sp" android:maxLines="1"/></LinearLayout>
MainActivity:
public class MainActivity extends Activity { private ImageView mImg; private TextView mStr; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.d("mydebug---", "onCreate : "+this.toString()); mImg = findViewById(R.id.iv_main_img); mStr = findViewById(R.id.tv_main_str); setInfo(); } private void setInfo(){ mImg.setImageResource(R.mipmap.online); mStr.setText(getString(R.string.app_name)); }}
运行截图(系统语言为台湾繁体):
资源配置完成,接下来看系统语言发生改变时,程序如何接收。先在清单文件给MainActivity配置:
android:configChanges="locale"
在MainActivity里添加:
@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); Log.d("mydebug---", "MainActivity onConfigurationChanged"); setInfo(); }
同时创建一个Application类,并在清单文件的application标签配置此类:
public class App extends Application { @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); Log.d("mydebug---", "App onConfigurationChanged"); }}
从名字就可以看出这两个onConfigurationChanged函数都是系统配置发生变动时的回调函数。
再次运行,如下操作:
输出日志:
10-16 21:42:28.310 15381-15381/hankin.international D/mydebug---: onCreate : hankin.international.MainActivity@d68835f10-16 21:42:35.230 15381-15381/hankin.international D/mydebug---: App onConfigurationChanged10-16 21:42:35.862 15381-15381/hankin.international D/mydebug---: onCreate : hankin.international.MainActivity@b236bc2
从日志可以看出在切换系统语言时,系统回调了application的onConfigurationChanged函数,但是MainActivity却重新创建了,这样会使程序逻辑非常不可控,我们需要的是MainActivity不重建,只回调onConfigurationChanged函数。接下来修改清单文件中MainActivity的配置为:
android:configChanges="locale|layoutDirection"
再次运行,重复上面的修改系统语言操作:
日志:
10-16 21:56:12.459 26881-26881/hankin.international D/mydebug---: onCreate : hankin.international.MainActivity@8e400d10-16 21:56:25.560 26881-26881/hankin.international D/mydebug---: App onConfigurationChanged10-16 21:56:27.051 26881-26881/hankin.international D/mydebug---: MainActivity onConfigurationChanged
可以看到MainActivity并没有重新创建了。这里需要注意的是MainActivity onConfigurationChanged是在回到应用程序的时候才会调用,且在onRestart之前调用。
应用随系统语言切换而改变写好后,可能还会碰到另一种需求:那就是在不管系统语言是什么,在应用内都显示成某种语言。
为了模拟这种需求我们在布局文件添加两个按钮:
<Button android:id="@+id/btn_main_en" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:onClick="click" android:text="设置为英文"/> <Button android:id="@+id/btn_main_zh" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:onClick="click" android:text="設置為繁體字"/>
在MainActivity中添加:
private void changeLanguage(String language) { //设置应用语言类型 Resources resources = getResources(); Configuration config = resources.getConfiguration(); DisplayMetrics dm = resources.getDisplayMetrics(); if (language.equals("en")) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { config.setLocale(Locale.ENGLISH); } else { config.locale = Locale.ENGLISH; } } else if(language.equals("zh")) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { config.setLocale(Locale.TAIWAN); } else { config.locale = Locale.TAIWAN; } } //只会改变此应用的Configuration,对于系统的getApplicationContext().getResources().getConfiguration().locale不变 //在应用被强制停止前,应用的Configuration都是更改后的Configuration resources.updateConfiguration(config, dm);//api25后推荐使用contenxt.createConfigurationContext(config); //更改了应用的Configuration后,不会回调其他函数,需要手动更新UI Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); startActivity(intent); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); Log.d("mydebug---", "MainActivity onNewIntent"); setInfo(); } public void click(View view){ switch (view.getId()){ case R.id.btn_main_en: changeLanguage("en"); break; case R.id.btn_main_zh: changeLanguage("zh"); break; } }
需要注意的是调用
resources.updateConfiguration(config, dm);
后,需要手动刷新一下页面,而且修改的Configuration会保存在当前进程,直到应用被杀死或接收到系统语言的改动。在实际开发中,这里可以做一个缓存,不管应用下次启动还是接受到系统语言的改动,都可以按用户设置的语言来显示app。
运行后,效果图:
项目源码
github下载
- 通俗易懂地讲解Android app国际化实现方式,开发需要注意的地方
- IOS APP测试需要注意的地方
- android 开发中需要注意内存泄露的地方
- Android WebView开发需要注意的地方和优化
- qt国际化与本地化中一个需要注意的地方
- 中国软件开发需要注意的地方
- XPCOM开发需要注意的地方
- 中国软件开发需要注意的地方
- 开发ALV时,需要注意的地方
- java开发初学者需要注意的地方
- CardView开发中需要注意的地方
- [APP开发技巧] 关于对象、数字、地理位置使用上需要注意的地方
- java序列化详细讲解,以及需要注意的地方
- android 混淆时需要注意的地方
- android自定义view需要注意的地方
- android手势监听需要注意的地方
- android studio快捷键需要注意的地方
- 需要注意的地方
- 最长公共子串(简化代码)
- Python进阶(三):*args,**kwargs的使用
- iOS获取键盘的高度
- java冒泡实现
- MySQL数据库锁机制之MyISAM引擎表锁和InnoDB行锁详解
- 通俗易懂地讲解Android app国际化实现方式,开发需要注意的地方
- windows下安装xgboost
- switch语句注意事项
- iOS7之后JavaScript与Objective-C之间的通信
- java 对象类型与基本数据类型传参的比较
- 编写servalet时引入第三方类抛出classnotfoundexception异常解决方法
- Linux_Arithmetic_Sequence
- C++ vector类模板和auto关键字
- Android AIDL简单分析