关键词:
简介
Android对应用进行换肤操作,首先要生成一个对应的皮肤包,在要换肤的应用中收集需要换肤的控件,获取皮肤包里的资源,一键换肤时遍历View树,对要换肤的控件进行换肤。下面总结为4个步骤
步骤
1 通过Activity.onCreateView()或 实现LayoutInfaltor.Factory2接口 创建收集可换肤控件
这项工作应该在YourActivity.class
或者BaseActivity.class
或者LifecycleObserver.class
中实现。这个步骤的实现自行搜索。
2 启动或触发换肤的时候加载皮肤包APK的资源
SkinManager.class
public void loaderSkinResources(skinPath)
//反射创建AssestManager并通过路径加载Apk的资源
//通过这个AssestManager获取Resource并用Map缓存
//创建资源管理器(此处不能用:application.getAssets())
AssetManager assetManager = AssetManager.class.newInstance();
// 由于AssetManager中的addAssetPath和setApkAssets方法都被@hide,目前只能通过反射去执行方法
Method addAssetPath = assetManager.getClass().getDeclaredMethod(ADD_ASSET_PATH, String.class);
// 设置私有方法可访问
addAssetPath.setAccessible(true);
// 执行addAssetPath方法
addAssetPath.invoke(assetManager, skinPath);
//==============================================================================
// 如果还是担心@hide限制,可以反射addAssetPathInternal()方法,参考源码366行 + 387行
//==============================================================================
// 创建加载外部的皮肤包(123456.skin,实质是APK)文件Resources(注:依然是本应用加载)
skinResources = new Resources(assetManager, appResources.getDisplayMetrics(), appResources.getConfiguration());
// 根据apk文件路径(皮肤包也是apk文件),获取该应用的包名。兼容5.0 - 9.0(亲测)
skinPackageName = application.getPackageManager().getPackageArchiveInfo(skinPath, PackageManager.GET_ACTIVITIES).packageName;
3 通过当前资源包的resourceId获取皮肤包里的资源
SkinManager.class
private int getSkinResourceIds(int resourceId)
// 优化:如果没有皮肤包或者没做换肤动作,直接返回app内置资源!
if (isDefaultSkin) return resourceId;
// 使用app内置资源加载,是因为内置资源与皮肤包资源一一对应(“netease_bg”, “drawable”)
String resourceName = appResources.getResourceEntryName(resourceId);
String resourceType = appResources.getResourceTypeName(resourceId);
// 动态获取皮肤包内的指定资源ID
// getResources().getIdentifier(“netease_bg”, “drawable”, “com.netease.skin.packages”);
int skinResourceId = skinResources.getIdentifier(resourceName, resourceType, skinPackageName);
4 通过applyViews(getWindow().getDecorView())遍历
这个是换肤过程
...........
SkinManager.getInstance().loaderSkinResources(skinPath);
if (themeColorId != 0)
int themeColor = SkinManager.getInstance().getColor(themeColorId);
StatusBarUtils.forStatusBar(this, themeColor);
NavigationUtils.forNavigation(this, themeColor);
ActionBarUtils.forActionBar(this, themeColor);
applyViews(getWindow().getDecorView());
..........................
/**
* 控件回调监听,匹配上则给控件执行换肤方法
*/
protected void applyViews(View view)
if (view instanceof ViewsMatch)
ViewsMatch viewsMatch = (ViewsMatch) view;
viewsMatch.skinnableView();
if (view instanceof ViewGroup)
ViewGroup parent = (ViewGroup) view;
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++)
applyViews(parent.getChildAt(i));
总结
文中所提及的4个步骤是实现换肤的基本原理,当然还有需要很多的优化,也还有兼容性问题,干货已给出啦~~
三步实现android应用内一键换肤,无需重启应用,无需编写多余代码(代码片段)
...家介绍一下现在比较主流的、Star比较多的换肤框架:Android-skin-support5.2KStar传送地址:https://github.com/x 查看详情
android几种换肤方式和原理分析(代码片段)
1.通过Theme切换主题通过在setContentView之前设置Theme实现主题切换。在styles.xml定义一个夜间主题和白天主题:<stylename="LightTheme"parent="Theme.AppCompat.Light.DarkActionBar"><itemname="co 查看详情
android几种换肤方式和原理分析(代码片段)
1.通过Theme切换主题通过在setContentView之前设置Theme实现主题切换。在styles.xml定义一个夜间主题和白天主题:<stylename="LightTheme"parent="Theme.AppCompat.Light.DarkActionBar"><itemname="colorPrimary">@color/co... 查看详情
android换肤框架搭建及使用(3完结篇)(代码片段)
本系列计划3篇:Android换肤之资源(Resources)加载(一)setContentView()/LayoutInflater源码分析(二)换肤框架搭建(三)—本篇tips:本篇只说实现思路,以及使用,具体细节请下载代码查看!本篇实现效果:fragment换肤recyclerView换肤自定义view属性换肤打... 查看详情
android换肤(全局换肤,部分换肤,字体替换,导航栏替换,自定义view换肤,夜间/日间模式)(代码片段)
采集大致流程监听所有activity的生命周期回调//SkinActivityLifecycleapplication.registerActivityLifecycleCallbacks(newSkinActivityLifecycle());创建activity的时候自定义布局工厂//SkinLayoutFactory@OverridepublicvoidonActivityCreat 查看详情
android手写实现插件化换肤兼容android10android11(代码片段)
...view及相关属性二、统一为所有Activity设置工厂(兼容Android9以上)三、加载皮肤包资源四、处理支持库或者自定义view的换肤五、处理状态栏换肤六、对代码动态设置颜色、背景的业务场景进行单独处理实现插件化换肤ÿ... 查看详情
android手写实现插件化换肤框架兼容android10android11(代码片段)
...view及相关属性二、统一为所有Activity设置工厂(兼容Android9以上)三、加载皮肤包资源四、处理支持库或者自定义view的换肤五、处理状态栏换肤六、对代码动态设置颜色、背景的业务场景进行单独处理实现插件化换肤ÿ... 查看详情
springboot一键换肤,soeasy!(代码片段)
...里松哥先来说下用法,然后我们再进行源码分析。1.一键换肤来做一个简单的需求,假设我的页面上有三个按钮,点击之后就能一键换肤,像下面这样:我们来看下这个需求怎么实现。首先三个按钮分别对应了... 查看详情
android-skin-support一款用心去做的android换肤框架(代码片段)
介绍Github地址:https://github.com/ximsfei/Android-skin-supportAndroid-skin-support:一款用心去做的Android换肤框架,极低的学习成本,极好的用户体验.重要的事情说三遍:只需要两行代码,就可以实现换肤,你值得拥有!!!只需要两行代码,就可以实现换... 查看详情
android换肤框架搭建及使用(3完结篇)(代码片段)
本系列计划3篇:Android换肤之资源(Resources)加载(一)setContentView()/LayoutInflater源码分析(二)换肤框架搭建(三)—本篇tips:本篇只说实现思路,以及使用,具体细节请下载代码查看!本篇实现效果:fragment换肤recyclerView换肤自定义view属性换肤打... 查看详情
android-skin-support一款用心去做的android换肤框架(代码片段)
介绍Github地址:https://github.com/ximsfei/Android-skin-supportAndroid-skin-support:一款用心去做的Android换肤框架,极低的学习成本,极好的用户体验.重要的事情说三遍:只需要两行代码,就可以实现换肤,你值得拥有!!!只需要两行代码,就可以实现换... 查看详情
金三银四2022android面经实录(代码片段)
1、项目经历,业务,难点2、Java基础,JVM,集合原理3、Android基础,View体系,View绘制流程,事件分发,屏幕刷新,动画原理4、常见三方库原理5、Jetpack6、AndroidFramework7、算法8、Kotlin方法重载问题,泛型相关word常用的三方库原理,... 查看详情
03布局原理与xml原理分析二(代码片段)
(1)使用插件化的方案为App换肤(2)不需要重启App就能够换肤(3)市场上所有的APP都可以当成自己的皮肤包来用。(4)无闪烁(5)便于扩展与维护,入侵性很小。(6)只需要... 查看详情
简述深浅拷贝原理(代码片段)
//数组浅拷贝vararr=["xjz","is","a","superman"];//slicevarnew_arr=arr.slice();new_arr[0]="zxb";console.log("before:"+arr);console.log("after:"+new_arr);//concatvarnew_arr=arr.concat();new_arr[0]="bb";consol 查看详情
02布局原理与xml原理分析(代码片段)
(1)使用插件化的方案为App换肤(2)不需要重启App就能够换肤(3)市场上所有的APP都可以当成自己的皮肤包来用。(4)无闪烁(5)便于扩展与维护,入侵性很小。(6)只需要... 查看详情
02布局原理与xml原理分析(代码片段)
(1)使用插件化的方案为App换肤(2)不需要重启App就能够换肤(3)市场上所有的APP都可以当成自己的皮肤包来用。(4)无闪烁(5)便于扩展与维护,入侵性很小。(6)只需要... 查看详情
制作一个百度换肤效果(代码片段)
原理就是获取到图片的src地址然后赋值给背景的URL地址<!DOCTYPEhtml><html><head><metacharset="CHARSET"><title></title><styletype="text/css">*margin:0;padding:0;bodybackground:url( 查看详情
一键生成android录屏gif的脚本(代码片段)
目的编写bash脚本,实现一行命令得到Android手机录制屏幕gif动图文件.博主使用ubuntu系统,shell为bash.这个脚本也可以用在mac系统上.听说windows系统出了ubuntuonwindows,不知道能不能使用这个脚本.原理adbshellscreenrecordAndroid4.4版本后系统内... 查看详情