当前位置: 首页 > news >正文

android 换肤框架详解1-换肤逻辑基本

  • 换肤框架流程

1,通过AssetManager获取换肤的资源文件

2,通过原文件中的resId获取到res名称和res类型,比如resId未R.color.red,这里的名称就是red,类型就是color

3,在换肤的资源文件AssetManager中,用原文件的resId的res名称和res类型获取到换肤资源文件中的ResId,在通过AssetManager.getXXX拿到对应的资源

4,将拿到的资源文件部署到View

  • 代码模块

1,创建资源包

由于资源包只需要里面的资源文件,多余的内容都可以删除到,这里只留如下内容

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true" /></manifest>

gradle中不需要其他的引用包

build.gradle.kts

plugins {id("com.android.application")
}android {namespace = "com.kx.skin"compileSdk = 33defaultConfig {applicationId = "com.kx.skin"minSdk = 28targetSdk = 33versionCode = 1versionName = "1.0"testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"}buildTypes {release {isMinifyEnabled = falseproguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"),"proguard-rules.pro")}}compileOptions {sourceCompatibility = JavaVersion.VERSION_1_8targetCompatibility = JavaVersion.VERSION_1_8}
}dependencies {
}

在原本的app和换肤资源的app中同时创建名称相同的资源

将编译好的skin apk放到assets目录下

  • 创建资源文件的AssetManager
    public static Resources getThemeResources(Context context) {try {//通过反射创建AssetManager
//            AssetManager assetManager = AssetManager.class.newInstance();
//            Method add = assetManager.getClass().getDeclaredMethod("addAssetPath", String.class);//通过反射加载路径
//            int cookie = (int) add.invoke(assetManager, "/sdcard/skin/skin.skin");//将assets中的文件拷贝到自己私有的文件中File skinFile = copyAssetToFiles(context,"skin-debug.apk",        // assets 下的相对路径"skin-debug.apk");            // 目标文件名boolean exists = skinFile.exists();   // true 表示存在Log.e(TAG, "加载文件 exists " + exists + " getAbsolutePath " + skinFile.getAbsolutePath());// 创建资源ResourcesAssetManager assetManager = new AssetManager();int cookie = assetManager.addAssetPath(skinFile.getAbsolutePath());if (cookie == 0) {Log.e(TAG, "加载失败,路径无效或权限不足");}Resources oldRes = context.getResources();Resources newRes = new Resources(assetManager,oldRes.getDisplayMetrics(),oldRes.getConfiguration());return newRes;} catch (Throwable e) {e.printStackTrace();Log.d(TAG, "Throwable " + e);}return null;}

2,在换肤的资源文件AssetManager中,用原文件的resId的res名称和res类型获取到换肤资源文件中的ResId,在通过AssetManager.getXXX拿到对应的资源

    public static int getThemeResourcesColorResId(Context context, int resId) {Log.d(TAG, "getThemeResourcesColor resId " + resId);Resources resources = context.getResources();//包名:资源类型/资源名
//        String resName = resources.getResourceName(resId);//返回格式:ic_launcher(仅资源名)R.drawable.ic_launcher,R.color.ic_launcherString resName = resources.getResourceEntryName(resId);//资源类型类型drawable,colorString typeName = resources.getResourceTypeName(resId);Log.d(TAG, "getThemeResourcesColor resName " + resName);Log.d(TAG, "getThemeResourcesColor typeName " + typeName);//获取主题资源文件Resources newResources = getThemeResources(context);//通过资源名称,获取到资源IDint newResId = newResources.getIdentifier(resName,        // 资源名typeName,           // 资源类型"com.kx.skin" // 应用包名);Log.d(TAG, "getThemeResourcesColor newResId " + newResId);//通过资源ID,获取到对应资源的值int newColorResId = newResources.getColor(newResId, null);Log.d(TAG, "getThemeResourcesColor newColorResId " + newColorResId);return newColorResId;}

代码调用

                int resId = ThemeModeChange.getThemeResourcesColorResId(ThemeActivity.this,R.color.content);tv_content.setBackgroundColor(resId);

http://www.xdnf.cn/news/1280269.html

相关文章:

  • 2025第十六届蓝桥杯大赛青少组省赛C++真题(初级组和中级组)
  • 数学建模——灰色预测(GM11)
  • 北京JAVA基础面试30天打卡07
  • HTTPS的应用层协议
  • react+vite-plugin-react-router-generator自动化生成路由
  • 安全等级认证系列 | 星环ArgoDB获CC EAL2安全认证,数据安全实力获国际认可
  • Linux入门DAY21
  • 用 Python 绘制企业年度财务可视化报告 —— 从 Excel 到 9 种图表全覆盖
  • 读《精益数据分析》:媒体内容平台全链路梳理
  • 低延迟RTSP|RTMP视频链路在AI驱动无人机与机器人操控中的架构实践与性能优化
  • TRS(总收益互换)系统架构设计:多市场交易的技术实现分析
  • 每日五个pyecharts可视化图表-line:从入门到精通 (3)
  • 常用设计模式系列(十九)- 状态模式
  • 闸机控制系统从设计到实现全解析:第 5 篇:RabbitMQ 消息队列与闸机通信设计
  • HBase BlockCache:LRU Cache
  • Agent用户体验设计:人机交互的最佳实践
  • redis(2)-java客户端使用(IDEA基于springboot)
  • 【图像处理基石】UE输出渲染视频,有哪些画质相关的维度和标准可以参考?
  • FlinkSql(详细讲解二)
  • IDE认知革命:JetBrains AI Assistant插件深度调教手册(终极实战指南)
  • 服务器配置实战:从 “密码锁” 到 “分工协作” 的知识点详解
  • POI导入时相关的EXCEL校验
  • Spring Boot Excel数据导入数据库实现详解
  • 缓存的三大问题分析与解决
  • Flink + Hologres构建实时数仓
  • MSE ZooKeeper:Flink高可用架构的企业级选择
  • 容器之王--Docker的安全优化详解及演练
  • 在Mac 上生成GitLab 的SSH 密钥并将其添加到GitLab
  • Django Request 与 DRF Request 的区别
  • (Arxiv-2025)Phantom:通过跨模态对齐实现主体一致性视频生成