skin-loader框架的换肤是通过插件化的形式替换资源文件,实现换肤效果。好处是可以在线更新皮肤换肤

Demo样例

流程

整个框架大概的流程是加载皮肤包,找到被标记的控件,通过自定义的Factory工程过滤掉其他控件,使用皮肤包中的资源文件更新被标记的ui。

使用操作

1、导入android-skin-loader框架包

androidStudio File->new->import Module选择android-skin-loader

项目右键->open Module Setting->app中加载依赖android-skin-loader库

2、在MyApplication 初始化框架

SkinManager.getInstance().init(this);

SkinManager.getInstance().load();

3、需要换肤的activity需要继承skin-loader中的BaseActivity

需要换肤的控件添加skin:enable=”true”,控件xml添加命名空间xmlns:skin=”http://schemas.android.com/android/skin”

4、准备需要替换的color或drawable同名的资源文件包将其打包,重命名以.skin结尾

本地测试可以使用adb命令将.skin包放在sdcard

adb push 文件目录/test.skin /sdcard

样例代码

xml文件,使用databinding,不知道的自行百度

xmlns:skin="http://schemas.android.com/android/skin">

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical">

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="horizontal">

android:id="@+id/btn_default"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textColor="@color/text_color"

android:background="@color/button_background"

skin:enable="true"

android:text="默认皮肤"/>

android:id="@+id/btn_change_skin"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginLeft="20dp"

android:textColor="@color/text_color"

android:background="@color/button_background"

skin:enable="true"

android:text="更改皮肤"/>

android:id="@+id/btn_add"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginLeft="20dp"

android:textColor="@color/text_color"

android:background="@color/button_background"

skin:enable="true"

android:text="动态添加布局"/>

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:textColor="@color/text_color"

android:text="文字文字文字文字文字文字"

skin:enable="true" />

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:src="@drawable/skin"

skin:enable="true"/>

android:id="@+id/add_layout"

android:layout_width="match_parent"

android:layout_height="wrap_content"

skin:enable="true"

android:orientation="vertical">

public class SkinChangeAct extends BaseActivity{

private ActivitySkinchangeBinding binding;

//skin包名

private String SKIN_NAME = "test.skin";

//skin皮肤包的路径

private String SKIN_DIR = Environment.getExternalStorageDirectory()+ File.separator+SKIN_NAME;

@Override

public void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

binding = DataBindingUtil.setContentView(this, R.layout.activity_skinchange);

//更换皮肤

binding.btnChangeSkin.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

File skin = new File(SKIN_DIR);

if(skin == null || !skin.exists()){

Toast.makeText(getApplicationContext(), "请检查" + SKIN_DIR + "是否存在", Toast.LENGTH_SHORT).show();

return;

}

SkinManager.getInstance().load(skin.getAbsolutePath(), new ILoaderListener() {

@Override

public void onStart() {

System.out.println("start");

}

@Override

public void onSuccess() {

System.out.println("onSuccess");

}

@Override

public void onFailed() {

System.out.println("onFailed");

}

});

}

});

//恢复默认皮肤

binding.btnDefault.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

SkinManager.getInstance().restoreDefaultTheme();

}

});

//动态加载控件

binding.btnAdd.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View view) {

dynamicAddTextView();

}

});

}

/**动态添加textview*/

private void dynamicAddTextView() {

TextView textView = new TextView(this);

RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

params.addRule(RelativeLayout.CENTER_IN_PARENT);

textView.setLayoutParams(params);

textView.setTextColor(SkinManager.getInstance().getColor(R.color.text_color));

textView.setText("hellohello");

textView.setTextSize(28);

//将动态添加的布局也更换皮肤,否则之前添加的不能更改

List mDanamicAttr = new ArrayList();

mDanamicAttr.add(new DynamicAttr(AttrFactory.TEXT_COLOR,R.color.text_color));

dynamicAddView(textView,mDanamicAttr);

binding.addLayout.addView(textView);

}

}

资源文件color.xml

#3F51B5

#303F9F

#FF4081

#ff0000

#00ff00

skin皮肤包中的资源文件color.xml

#3F51B5

#303F9F

#FF4081

#ffff00

#00ffff

对比一下,只是更改了数值,名字相同。

框架迭代,增加功能

android-skin-loader框架是没有对于src属性的修改,案例中使用imageView模拟了src的更改。

在AttrFactory中增加对于src的支持

public class AttrFactory {

public static final String BACKGROUND = "background";

public static final String TEXT_COLOR = "textColor";

public static final String LIST_SELECTOR = "listSelector";

public static final String DIVIDER = "divider";

//增加src属性

public static final String SRC="src";

public static SkinAttr get(String attrName, int attrValueRefId, String attrValueRefName, String typeName){

SkinAttr mSkinAttr = null;

System.out.println("attrName="+attrName);

if(BACKGROUND.equals(attrName)){

mSkinAttr = new BackgroundAttr();

}else if(TEXT_COLOR.equals(attrName)){

mSkinAttr = new TextColorAttr();

}else if(LIST_SELECTOR.equals(attrName)){

mSkinAttr = new ListSelectorAttr();

}else if(DIVIDER.equals(attrName)){

mSkinAttr = new DividerAttr();

}else if(SRC.equals(attrName)){

//自定义加载src

mSkinAttr =new SrcAttr();

}else{

return null;

}

mSkinAttr.attrName = attrName;

mSkinAttr.attrValueRefId = attrValueRefId;

mSkinAttr.attrValueRefName = attrValueRefName;

mSkinAttr.attrValueTypeName = typeName;

return mSkinAttr;

}

/**

* Check whether the attribute is supported

* @param attrName

* @return true : supported

* false: not supported

*/

public static boolean isSupportedAttr(String attrName){

if(BACKGROUND.equals(attrName)){

return true;

}

if(TEXT_COLOR.equals(attrName)){

return true;

}

if(LIST_SELECTOR.equals(attrName)){

return true;

}

if(DIVIDER.equals(attrName)){

return true;

}

//支持src

if(SRC.equals(attrName)){

return true;

}

return false;

}

}

srcAttr继承SkinAttr定义加载src

public class SrcAttr extends SkinAttr{

@Override

public void apply(View view) {

if(view instanceof ImageView){

ImageView imageView = (ImageView) view;

if(RES_TYPE_NAME_COLOR.equals(attrValueTypeName)){

imageView.setImageResource(SkinManager.getInstance().getColor(attrValueRefId));

}else if(RES_TYPE_NAME_DRAWABLE.equals(attrValueTypeName)){

Drawable bg = SkinManager.getInstance().getDrawable(attrValueRefId);

imageView.setImageDrawable(bg);

}

}

}

}

各种控件的支持都可以自己添加。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

android l风格皮肤,基于Android-Skin-Loader实现换肤效果相关推荐

  1. android l风格cm10主题,Android 4.3的CM10.2

    cm团队称有11款新设备获得cm团队的官方支持,分别是: 三星galaxy s relay 4g 三星galaxy s4–c spire 三星verizon galaxy note 10.1 lte ...

  2. Android开发自学笔记(基于Android Studio1.3.1)—1.环境搭建(转)

    一.引言    本套学习笔记的开发环境是Windows 10 专业版和Android Studio 的最新版1.3.1. Android Studio 是一个Android开发环境,基于Intelli ...

  3. Android开发自学笔记(基于Android Studio1.3.1)—1.环境搭建

    一.引言 本套学习笔记的开发环境是Windows 10 专业版和Android Studio 的最新版1.3.1. Android Studio 是一个Android开发环境,基于IntelliJ I ...

  4. Android开发介绍(基于Android Studio软件)

    Android开发介绍(基于Android Studio软件) 关于Android开发,笔者走过一些弯路,因此今天总计了有关Android开发的一些内容和心得,希望对大家有所帮助.首先来一张安卓开发者 ...

  5. 解决在使用skin.support:skin-support换肤控件报错问题

    解决在使用skin.support:skin-support换肤控件报错问题 1.如果项目中还在使用support库,添加以下依赖 implementation 'skin.support:skin- ...

  6. 基于Android的备忘录软件,基于Android的手机备忘录软件设计

    <基于Android的手机备忘录软件设计>由会员分享,可在线阅读,更多相关<基于Android的手机备忘录软件设计(25页珍藏版)>请在皮匠网上搜索. 1.课程设计报告(本科) ...

  7. 基于android的检测心率,基于android手机的血氧饱和度检测

    67 基于 android手机的血氧饱和度检测 许方成,赵曙光,杨 峰,黄佳佳 (东华大学信息科学与技术学院,上海 201620) 摘要:血氧饱和度是人体健康状况的标准指标,连续记录血氧饱和度可以预测 ...

  8. android studio绘制统计图,基于Android Studio的饼图账单的设计与开发_毕业论文.doc

    基于Android Studio的饼图账单的设计与开发_毕业论文 Anhui Vocactional & Technical College of Industry & Trade 毕 ...

  9. 基于android的地图毕业设计,基于android百度地图应用系统_毕业设计.docx

    基于android百度地图应用系统_毕业设计 南京晓庄学院2015届本科毕业论文 分类号: 学校代码:11460 学 号南京晓庄学院本科生毕业设计 基于Android平台和百度地图的应用系统 Appl ...

最新文章

  1. IOS之UITabBarController
  2. 第二讲、Linux的系统安装
  3. badboy测试工具下载
  4. Java中几个主流的数据库连接池
  5. asp.net core安全事项(下)
  6. PAT1015 德才论(C++)
  7. Chrome 73 DevTools 新功能之 Logpoints
  8. python sanic_Sanic框架安装与简单入门示例
  9. 台式计算机关机后自行重启,台式机电脑总是自动关机重启该怎么解决?
  10. Springboot在线电影系统实战开发
  11. iOS网络开发(5)请求的缓存
  12. mysql 前n个最大值_选择MySQL中的第n个最大值
  13. java volatile i_为啥Java里面volatile 修饰的i++还是线程不安全的
  14. 调整VirtualBox虚拟机分辨率的方法
  15. 烤箱定时器不走怎么办_走夜路害怕怎么办?带上这6大辟邪文玩在也不害怕
  16. 微pe工具箱 系统安装教程_微PE工具箱 V2.0正式版(附安装系统教程)
  17. oracle11g dos卸载,Oracle 11G 完全卸载
  18. 独立站怎么做SEO?
  19. NDK-r25交叉编译qemu-7.0.0 第66步报错
  20. YOLOv5剪枝✂️| 模型剪枝实战篇

热门文章

  1. 非法收集儿童数据,微软与 2000w 美元和解
  2. php压缩图片,PHP压缩图片功能的介绍
  3. just read 人生信条!
  4. JVM类加载机制、破坏双亲委派
  5. JVM调优参数: XSS,XMS,XMX
  6. Linux系统基础学习笔记1
  7. springboot自动装配到底是什么意思?
  8. python海龟编辑器中询问并获得输入咱弄出来的积木_源码图鉴
  9. __bridge,__bridge_retained和__bridge_transfer的意思,区别与使用
  10. Linux(RedHat)下日期时间的设置