加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 业界 > 正文

网易云音乐、手机QQ的换肤是怎么做到的

发布时间:2019-09-20 15:47:28 所属栏目:业界 来源:rongchuang
导读:Android的主题换肤 ,可插件化提供皮肤包,无需Activity的重启直接实现无缝切换,可高仿网易云音乐的主题换肤。 这个链接是本次的Demo打包出来的样本SkinChangeDemo,可以去下载下来先试试效果,皮肤文件需放到存储卡的根目录下。 关于Android的主题换肤都

我们都知道在Android中如果想去获取资源文件都必须通过Resources去获取。这个库的核心思想就是动态的去加载第三方包里面的包,获取到其Resources然后以获取到的这个Resources去获取第三方包里面的资源内容,最后设置到我们有需响应皮肤更改的View上。

这里我就只介绍load和base两个包,其他包的内容在讲解的时候会涉及到

1.load包

我们先来看看这个load包里面的内容(其实这里就是今天核心内容的核心)。

网易云音乐、手机QQ的换肤是怎么做到的

里面有两个类文件:SkinInflaterFactory、SkinManager

我们先来看看SkinManager的实现,直接跳到load方法

  1. public void load(String skinPackagePath, final ILoaderListener callback) { 
  2.  new AsyncTask<String, Void, Resources>() { 
  3.  protected void onPreExecute() { 
  4.  if (callback != null) { 
  5.  callback.onStart(); 
  6.  } 
  7.  } 
  8.  @Override 
  9.  protected Resources doInBackground(String... params) { 
  10.  try { 
  11.  if (params.length == 1) { 
  12.  String skinPkgPath = params[0]; 
  13.  Log.i("loadSkin", skinPkgPath); 
  14.  File file = new File(skinPkgPath); 
  15.  if (file == null || !file.exists()) { 
  16.  return null; 
  17.  } 
  18.  PackageManager mPm = context.getPackageManager(); 
  19.  PackageInfo mInfo = mPm.getPackageArchiveInfo(skinPkgPath, PackageManager.GET_ACTIVITIES); 
  20.  skinPackageName = mInfo.packageName; 
  21.  AssetManager assetManager = AssetManager.class.newInstance(); 
  22.  Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class); 
  23.  addAssetPath.invoke(assetManager, skinPkgPath); 
  24.  Resources superRes = context.getResources(); 
  25.  Resources skinResource = new Resources(assetManager, superRes.getDisplayMetrics(), superRes.getConfiguration()); 
  26.  SkinConfig.saveSkinPath(context, skinPkgPath); 
  27.  skinPath = skinPkgPath; 
  28.  isDefaultSkin = false; 
  29.  return skinResource; 
  30.  } 
  31.  return null; 
  32.  } catch (Exception e) { 
  33.  e.printStackTrace(); 
  34.  return null; 
  35.  } 
  36.  } 
  37.  protected void onPostExecute(Resources result) { 
  38.  mResources = result; 
  39.  if (mResources != null) { 
  40.  if (callback != null) callback.onSuccess(); 
  41.  notifySkinUpdate(); 
  42.  } else { 
  43.  isDefaultSkin = true; 
  44.  if (callback != null) callback.onFailed(); 
  45.  } 
  46.  } 
  47.  }.execute(skinPackagePath); 
  48.  } 

这个方法有两个参数,第一个是皮肤包的路径,第二个就是一个简单的回调

其中doInBackground方法里面就实现了动态的去获取皮肤包的Resources,当获取成功之后,在onPostExecute方法中就将这个Resources赋值到我们定义好的变量中去,以方便我们之后的使用,注意到当获取到的这个Resources不为空时,也就是我们已经获取到了皮肤包里面的资源,我们就调用notifySkinUpdate()这个方法来通知界面去更改皮肤,如果为空就还是使用默认的皮肤。

我们来看看notifySkinUpdate()的实现

网易云音乐、手机QQ的换肤是怎么做到的

这里很简单,就是去遍历mSkinObservers这个集合,然后去通知更新。对于ISkinUpdate是一个接口,每个需要皮肤更新的Activity都需要去实现这个接口。

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读