What is XSkinLoader
XSkinLoader是Android上即时换肤框架。能够动态加载Apk文件中的资源文件,实现即时换肤。
引用
代码已经上传到Jcenter
gradle:
implementation 'com.windysha.xskinloader:xskinloader:0.1.0'
maven:
<dependency>
<groupId>com.windysha.xskinloader</groupId>
<artifactId>xskinloader</artifactId>
<version>0.1.0</version>
<type>pom</type>
</dependency>
使用
加载资源Apk
只需要将资源Apk拷贝到sdcard下面,调用loadSkin进行加载:
String skinApkPath = "mnt/sdcard/skin.apk";
SkinManager.get().loadSkin(skinApkPath);
如果需要恢复到默认皮肤(使用宿主Apk资源),调用restoreToDefaultSkin()即可:
SkinManager.get().restoreToDefaultSkin();
Activity中布局文件换肤
对于需要换肤的Activity,在Activity的setContentView方法调用之前,设置其LayoutInflater的Factory接口:
SkinInflaterFactory.setFactory(this);
这样,使用Activity的LayoutInflater加载的xml布局就可以支持换肤了。
设置Application的LayoutInflater
如果使用Application Context的LayoutInflater加载View也需要换肤,在Application的onCreate中加上这样一行代码:
SkinInflaterFactory.setFactory(LayoutInflater.from(this));
如此,使用LayoutInflater.from(context.getApplicationContext()).inflate()加载的view也是可以换肤。
XML换肤
xml布局中的View需要换肤的,只需要在布局文件中相关View标签下添加skin:enable="true"
即可,例如:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:skin="http://schemas.android.com/android/skin"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/status_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
skin:enable="true"
android:background="@color/title_color">
</TextView>
<RelativeLayout/>
能换肤的前提是解析这个xml的LayoutInflater设置Factory接口:SkinInflaterFactory
因此,在相关activity的onCreate()
中setContentView()
方法之前添加:
//干涉xml中view的创建,实现xml中资源换肤
SkinInflaterFactory.setFactory(this); //for skin change in XML
PS: 对于AppCompatActivity,务必要在
onCreate()
的super.onCreate()
之前添加,否则不会使用AppComt包装的控件,比如:AppCompatTextView等。
某些view的资源是在代码中动态设置的,使用以下方式来设置资源,才能实现换肤效果:
//设置imageView的src资源
SkinManager.get().setImageDrawable(imageView, R.drawable.ic_action);
//设置imageView的backgroud资源
SkinManager.get().setViewBackground(imageView, R.drawable.ic_action);
//设置textVie的color资源
SkinManager.get().setTextViewColor(textView, R.color.title_color);
//设置Activity的statusBarColor
SkinManager.get().setWindowStatusBarColor(MainActivity.this.getWindow(), R.color.title_color);
...
xml中指定换肤属性
xml中假如出现了多个可换肤属性,但只需要换其中部分属性,而不是全部属性,比如:
<Button
android:id="@+id/use_sdcard_skin"
android:layout_width="180dp"
android:layout_height="40dp"
skin:enable="true"
android:background="@drawable/confirm_skin_btn_border"
android:textColor="@color/music_skin_change_button_color" />
这个布局中,包含两个换肤属性:background
,textColor
,假如只想换textColor
,那该怎么办?
此处,借鉴了[andSkin][9]中的一个办法,增加一个属性attrs
,在此属性中声明需要换肤的属性。
具体到上面的例子,只需要增加这样一行代码skin:attrs="textColor"
就行:
<Button
android:id="@+id/use_sdcard_skin"
android:layout_width="180dp"
android:layout_height="40dp"
skin:enable="true"
skin:attrs="textColor"
android:background="@drawable/confirm_skin_btn_border"
android:textColor="@color/music_skin_change_button_color" />
如果支持多个属性,使用|
分割就行:
skin:attrs="textColor|background"
其实,大多数情况下并不用在Xml中加此属性来控制,如若不想此属性换肤,也可以在相应的皮肤apk中去掉此属性指定的资源。
新增换肤属性
对已经成型的大型项目来说,XSkinLoader中提供的换肤属性是不够用的,需要额外增加的换肤属性该怎么办? 在sample中写好了相应的模板,具体参考ExtraAttrRegister.java
public static final String CUSTIOM_VIEW_TEXT_COLOR = "titleTextColor";
static {
//增加自定义控件的自定义属性的换肤支持
SkinResDeployerFactory.registerDeployer(CUSTIOM_VIEW_TEXT_COLOR, new CustomViewTextColorResDeployer());
}
新增style中的换肤属性
假如style中的换肤属性不够用,需要新增,该怎么办? sample中也写了一个模板,在ExtraAttrRegister.java中:
static {
//增加xml里的style中指定的View background属性换肤
StyleParserFactory.addStyleParser(new ViewBackgroundStyleParser());
}
源码分析
请参考我的个人博客:侵入性低扩展性强的Android换肤框架XSkinLoader的用法及原理
License
Copyright 2018 Windy
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.