当前位置: 首页 > 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.dtcms.com/a/325636.html

相关文章:

  • R语言机器学习算法实战系列(二十七)LASSO 与 Adaptive LASSO 在特征选择中的比较与应用
  • 为什么TEXT不区分大小写,而BLOB严格区分?
  • 剑桥大学最新研究:基于大语言模型(LLM)的分子动力学模拟框架,是MD的GPT时刻还是概念包装?
  • Selenium竞品价格监控爬虫(代理防封版)
  • C语言模拟 MCU 上电后程序的执行顺序 + 回调函数机制 + 程序计数器(PC)和堆栈的作用
  • PID 控制算法 | stm32 直流电机控制
  • 从零开始的云计算生活——项目实战容器化
  • 当生产环境卡成 PPT:Spring Boot 线程 Dump 捉妖指南 - 第544篇
  • AI入门学习--如何写好prompt?
  • STM32学习笔记7-TIM输入捕获模式
  • 1000w小时语音数据!语音模型Higgs Audio V2情感能力跃迁;MathCaptcha10k提升验证码识别技术
  • 主DNS部署+辅助DNS服务器部署
  • 嵌入式学习(Day24)fread/fwrite
  • 【华为机试】208. 实现 Trie (前缀树)
  • 钓鱼鱼饵制作的方式
  • 【项目测试】:问卷考试系统项目测试报告
  • FlinkSql(详细讲解一)
  • C#中如何运用JWT用户认证
  • AT24C02C-SSHM-T用法
  • 什么情况下会导致日本服务器变慢?解决办法
  • 系统编程——消息队列
  • 前端实现 MD5 + AES 加密的安全登录请求
  • Nacos-1--什么是Nacos?
  • 疫情可视化:基孔肯雅热风险地图实战解析
  • Dubbo从入门到实战:分布式服务开发指南
  • WPF之绑定!
  • OpenCV计算机视觉实战(19)——特征描述符详解
  • 玩转Docker | 使用Docker部署Trilium Notes知识库工具
  • typecho博客设置浏览器标签页图标icon
  • 石材 × 设计:解锁永恒材质的四大灵感密码