车载定制化系统设置中实现平滑的语言切换

在每个车载系统中,都会有自己独特的UI风格。比如系统设置这个功能,为了统一风格,我们不能直接去调用Android原生的设置应用,而是应该重新做一个风格统一的符合需求的系统设置应用。我们要说的语言切换这个功能,就是其中一个设置项。
如果简单地实现语言切换,应该是比较简单的,就是利用反射重新设置一下Locale就好了,这个时候Activity会异常销毁,并会重新加载刷新当前语言资源。如下:

	public static void setLanguage(Locale locale){
		try {
			Class c =  Class.forName("com.android.internal.app.LocalePicker");
			Object obj = c.newInstance();
			Method method = c.getMethod("updateLocale", new Class[] {Locale.class});
			method.invoke(obj, locale);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}catch (InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
		}catch (NoSuchMethodException e) {
			e.printStackTrace();
		}catch (IllegalArgumentException | InvocationTargetException e) {
			e.printStackTrace();
		}
	}

但是客户的需求可没这么简单,首先他不会允许你有一个销毁再新创建的闪一下的动作,其次会要求增加一个带loading动画的弹窗效果。
第一个需求的解决,是在Manifest文件中对应的设置语言的那个Activity增加属性: android:configChanges=“locale|layoutDirection”。这样Activity就不会自动销毁了。但同时,我们需要注册一个广播接收器,监听语言改变的广播,在这里需要把Activity里面的相关字符串重新加载一遍,实现手动的刷新。如下:

/** 注册语言改变广播 */
	private void registerLocalReceiver() {
		IntentFilter mFilter = new IntentFilter();
		mFilter.addAction(Intent.ACTION_LOCALE_CHANGED);
		this.registerReceiver(localReceiver, mFilter);
	}
	
	private BroadcastReceiver localReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context arg0, Intent arg1) {
			Log.i(TAG, "receive the language changed broadcast!");
			initData();
		}
	};
@Override
	public void initData() {
		mTvTitle.setText(getStr(R.string.set_usually));
		mIvTitle.setImageResource(R.drawable.set_usually_n);
		.......
	}

第二个需求,需要在切换语言的同时,还要有一个loading动画的弹窗效果。如果只是单纯地在应用中使用windowManager添加一个view,并利用动画去转动,很大概率会出现动画卡顿的效果,主要是动画的操作,只能放在主线程去做。于是可以把语言切换和动画的效果,放在另外的进程去处理,这样就可以实现平滑的语言切换了。弹窗的实现效果如下:

private void showUpdateLanguageDialog(View view){
		try{
			WindowManager mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
			WindowManager.LayoutParams mWindowParams = new WindowManager.LayoutParams();
			mWindowParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
			mWindowParams.format = PixelFormat.TRANSLUCENT;
			mWindowParams.gravity = Gravity.LEFT | Gravity.TOP;
			mWindowParams.x = 0;
			mWindowParams.y = 0;
			mWindowParams.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
					| WindowManager.LayoutParams.FLAG_FULLSCREEN
					| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
			mWindowParams.width = WindowManager.LayoutParams.MATCH_PARENT;
			mWindowParams.height = WindowManager.LayoutParams.MATCH_PARENT;
			mWindowManager.addView(view, mWindowParams);
		}catch(Exception ex){
			
		}
	}

由于Locale是不能通过Parcelable传递的,所以使用Configuration来传递,切换语言也可以用下面的方式:

IActivityManager iActMag = ActivityManagerNative.getDefault();
		try {
			Configuration config = iActMag.getConfiguration();
			config.locale = locale;
			// 此处需要声明权限:android.permission.CHANGE_CONFIGURATION
			// 会重新调用 onCreate();
			iActMag.updateConfiguration(config);
		} catch (RemoteException e) {
			e.printStackTrace();
		}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值