Android一键换肤功能:一种简单的实现

现在的APP开发,通常会提供APP的换肤功能,网上流传的换肤代码和实现手段过于复杂,这里有一个开源实现,我找了一大堆,发现这个项目相对较为简洁:https://github.com/hongyangAndroid/AndroidChangeSkin


但是该项目的代码不晓得是咋回事,导入到Android studio里面后报出很多错误,我把原作者的代码重新整理抽取出来,转换成Eclipse项目,重新整理成正确、可直接运行的项目,重新push到github上,新的github链接地址:https://github.com/zhangphil/Android-ChangeSkin


代码包中的changeskin_demo是原作者的演示代码,AppTest是我写的一个更为简单的例子。

本文接下去以AppTest项目代码为例。

代码运行结果如图。

假设默认是黄色皮肤:

换肤成红色:

换肤成绿色:

使用方式:

1,首先要自定义一个Application,在AppTest中就是MyApplication。完成初始化。

package zhangphil.apptest;

import com.zhy.changeskin.SkinManager;

import android.app.Application;

public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
SkinManager.getInstance().init(this);
}
}

2,把这个MyApplication写到Androidmanifest.xml里面:

3,在打算实现换肤的activity里面的onCreate()和onDestory()里面添加相应的“注册”和“注销”代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
SkinManager.getInstance().register(this);
...
} @Override
protected void onDestroy(){
super.onDestroy();
SkinManager.getInstance().unregister(this);
}

本例完整的MainActivity.java代码:

package zhangphil.apptest;

import com.zhy.changeskin.SkinManager;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem; public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); SkinManager.getInstance().register(this); setContentView(R.layout.activity_main);
} @Override
protected void onDestroy(){
super.onDestroy();
SkinManager.getInstance().unregister(this);
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.red_skin) {
SkinManager.getInstance().changeSkin("red");
return true;
} if (id == R.id.green_skin) {
SkinManager.getInstance().changeSkin("green");
return true;
} if (id == R.id.default_skin) {
SkinManager.getInstance().changeSkin("default");;
return true;
} return super.onOptionsItemSelected(item);
}
}

以上完成后,剩下的就是比较繁琐和稍微需要理解的难点。

以Android ImageView为例,假设要对某一个ImageView实现一键换肤功能,在本例是要将ImageView的src图片换成相应的皮肤颜色,那么首先需要准备几套以一个共同前缀名和不同后缀名组成的图片资源,本例是:



skin_img_green.png

skin_img_red.png

skin_img_default.png

相同的前缀名是skin_img  ,不同的后缀名是 green,red,default,后缀名至关重要,后面将以后缀名换肤。中间用连词符“_”连接起来。

然后在ImageView里面添加tag字段属性。Tag字段属性有三部分组成,以本例的ImageView为例,第一部分skin是固定的,不用管。接着就是上面的前缀 skin_img,第三部分是作为ImageView的src为靶子换肤。

<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:tag="skin:skin_img:src"
android:src="@drawable/skin_img_default"/>

TextView类似于ImageView,TextView的字段tag也是三段,第一部分skin不用管,第二部分仍然是需要设置的颜色的前缀,第三部分是修改的TextView的属性textColor为标靶。TextView的配置代码:

<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/image"
android:layout_centerHorizontal="true"
android:text="Zhang Phil @CSDN"
android:tag="skin:text_color:textColor"
android:textColor="@color/text_color_default" />

colors.xml定义的相关属性:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="text_color_red">#ff0000</color>
<color name="text_color_green">#00ff00</color>
<color name="text_color_default">#ffff00</color>
</resources>

本例的换肤在menu菜单里面触发,就直接以之前定义的ImageView和TextView的不同后缀名:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.red_skin) {
SkinManager.getInstance().changeSkin("red");
return true;
} if (id == R.id.green_skin) {
SkinManager.getInstance().changeSkin("green");
return true;
} if (id == R.id.default_skin) {
SkinManager.getInstance().changeSkin("default");;
return true;
} return super.onOptionsItemSelected(item);
}

更为全面的说明不如直接看我写的AppTest这个项目代码,项目源代码例子我尽量写的比较简单。

Android一键换肤功能:一种简单的实现的更多相关文章

  1. 一种简单的实现:Android一键换肤功能

    现在的APP开发,通常会提供APP的换肤功能,网上流传的换肤代码和实现手段过于复杂,我把原作者的代码重新整理抽取出来,转换成Eclipse项目,重新整理成正确.可直接运行的项目. 代码运行结果如图. ...

  2. Android实现换肤功能(一)

    上周有个朋友给建议说讲讲换肤吧,真巧这周公司的工作安排也有这个需求,换的地方之多之繁,让人伤神死了.正所谓磨刀不误砍柴工,先磨下刀,抽出一个工具类,写了个关于换肤的简单demo. Android中换肤 ...

  3. Android实现换肤功能(二)

    前两天写的上章关于换肤的功能获得了很好的反响,今天为大家介绍另一种方式.今天实现的策略也是网友建议的,然后我自己去写了个demo,大家自己评估下相比第一种方式的优势和劣势在哪里. 简单介绍下关于第一种 ...

  4. Android 换肤功能的实现(Apk插件方式)

    一.概述 由于Android 没有提供一套统一的换肤机制,我猜可能是因为国外更注重功能和体验的原因 所以国内如果要做一个漂亮的换肤方案,需要自己去实现. 目前换肤的方法大概有三种方案: (1)把皮肤资 ...

  5. Android插件化的思考——仿QQ一键换肤,思考比实现更重要!

    Android插件化的思考--仿QQ一键换肤,思考比实现更重要! 今天群友希望写一个关于插件的Blog,思来想去,插件也不是很懂,只是用大致的思路看看能不能模拟一个,思路还是比较重要的,如果你有兴趣的 ...

  6. Android QMUI实战:实现APP换肤功能,并自动适配手机深色模式

    Android换肤功能已不是什么新鲜事了,市面上有很多第三方的换肤库和实现方案. 之所以选择腾讯的QMUI库来演示APP的换肤功能,主要原因: 1.换肤功能的实现过程较简单.容易理解: 2.能轻松适配 ...

  7. Flex AIR应用换肤功能(Android和IOS)

    说明 换肤功能,即将整个应用的皮肤都进行更换,其实质,是动态加载swf文件的过程,而这些swf文件则有css文件编译而来. 关于换肤功能,在android和ios系统的实现方式是不同的.主要原因,是因 ...

  8. Android主题换肤 无缝切换

    2016年7月6日 更新:主题换肤库子项目地址:ThemeSkinning,让app集成换肤更加容易.欢迎star以及使用,提供改进意见. 更新日志: v1.3.0:增加一键切换切换字体(初版)v1. ...

  9. Android主题换肤实现

    本系列文章主要是对一个Material Design的APP的深度解析,主要包括以下内容 基于Material Design Support Library作为项目整体框架.对应博文:Android ...

随机推荐

  1. 使用WCF进行跨平台开发之一(WCF的实现、控制台托管与.net平台的调用)

    WCF是Windows Communication Foundation的缩写,是微软发展的一组数据通信的应用程序开发接口,它是.NET框架的一部分,是WinFx的三个重要开发类库之一,其它两个是WP ...

  2. codeforces 949B A Leapfrog in the Array

    B. A Leapfrog in the Array time limit per test 2 seconds memory limit per test 512 megabytes input s ...

  3. [BZOJ 1691] 挑剔的美食家

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1691 [算法] 不难想到如下算法 : 将所有牛和牧草按鲜嫩程度降序排序,按顺序扫描, ...

  4. openstack service glance-api/registry mysql of max_connection

  5. Bitmap与String之间的转换

    /** * 将bitmap转换成base64字符串 * * @param bitmap * @return base64 字符串 */ public String bitmaptoString(Bit ...

  6. BZOJ 2592 随机化(伪)

    思路: 放yousiki大爷题解 http://yousiki.net/index.php/archives/82/ 我写的是随机化 既然gzz证了最终答案的上界是O(N)的 那么我们可以n^2枚举所 ...

  7. 题解报告:hdu 1272 小希的迷宫

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1272 Problem Description 上次Gardon的迷宫城堡小希玩了很久(见Problem ...

  8. Android开发中的SQLite事务处理,即beginTransaction()方法

    使用SQLiteDatabase的beginTransaction()方法可以开启一个事务,程序执行到endTransaction() 方法时会检查事务的标志是否为成功,如果程序执行到endTrans ...

  9. html基础代码演示2

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...

  10. 关于vector.size()和string.length() 的返回类型 size_type

    今天写循环的时候碰到一个问题,发现:string.length()返回的类型是size_type.它是unsigned 类型.string::size_type它在不同的机器上,长度是可以不同的,并非 ...