Android 动态换肤技术原理实践及总结

本文详细介绍了Android动态换肤的实现原理,包括对需要换肤的View进行标记、创建皮肤包资源库、加载皮肤包资源,并通过实例展示了如何替换TextView的颜色和背景。通过这些步骤,实现了在运行时动态改变应用的主题和视觉样式。
摘要由CSDN通过智能技术生成

此文来自阿钟的投稿,阅读大约15分钟

实现的效果图

动态换肤一般实现的原理

  1. 对页面需要换肤的View进行标记

  2. Activity#setContentView()加载view时获取到标记的view(后面会说是要怎么获取到)

  3. 创建一个Library项目制作我们的皮肤包(res下的资源名称需要与app使用的一致,换肤就是通过使用的资源名称去皮肤包里加载相同名字的资源)

  4. 创建皮肤包对应的Resources对象(用于加载皮肤包内的资源)

  5. 点击换肤将我们标记的View的一些属性上设置的值修改为皮肤包里的值,这样就达到换肤的效果

一、对页面需要换肤的View进行标记

这一步是相对简单的,只要自定义一个属性即可;在获取View的时候判断有无这个属性 有就将这个view存起来

 1<?xml version="1.0" encoding="utf-8"?>
 2<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3    xmlns:skin="http://schemas.android.com/apk/azhon-skin"
 4    xmlns:tools="http://schemas.android.com/tools"
 5    android:layout_width="match_parent"
 6    android:layout_height="match_parent"
 7    android:orientation="vertical"
 8    android:padding="16dp"
 9    tools:context=".MainActivity">
10    <TextView
11        android:layout_width="wrap_content"
12        android:layout_height="wrap_content"
13        android:background="@color/bg_1"
14        android:text="我是一个TextView"
15        android:textColor="@color/title_1"
16        android:textSize="16sp"
17        skin:enable="true" />
18    <Button
19        android:id="@+id/btn_dark"
20        android:layout_width="match_parent"
21        android:layout_height="wrap_content"
22        android:layout_marginTop="20dp"
23        android:background="@color/bg_2"
24        android:text="@string/btn_text"
25        android:textColor="@color/title_2"
26        skin:enable="true" />
27    <Button
28        android:id="@+id/btn_default"
29        android:layout_width="match_parent"
30        android:layout_height="wrap_content"
31        android:layout_marginTop="20dp"
32        android:background="@color/bg_3"
33        android:text="@string/btn_reset_text"
34        android:textColor="@color/title_3" />
35</LinearLayout>

skin:enable="true"这个就是自定的一个属性取值为boolean,如果为true就表示在换肤的时候需要去皮肤包加载对应的资源 ¨K15K **这里使用的是自定义布局加载器LayoutInflaterLayoutInflater.Factory2 `来监听View的创建;下面我们来通过阅读源码来具体说一下为什么使用的这个:**

查看AppCompatActivity的setContentView()方法

1public class MainActivity extends AppCompatActivity {
2    @Override
3    protected void onCreate(Bundle savedInstanceState) {
4        super.onCreate(savedInstanceState);
5        setContentView(R.layout.activity_main);
6}

接着继续调用了getDelegate()的setContentView()方法

1// AppCompatActivity.java
2@Override
3public void setContentView(@LayoutRes int layoutResID) {
4    getDelegate().setContentView(layoutResID);
5}

getDelegate()获取到的是AppCompatDelegate这个抽象类的实现类,而他的实现类就只有一个AppCompatDelegateImpl

接着调用了AppCompatDelegateImpl的setContentView()


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值