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这个项目代码,项目源代码例子我尽量写的比较简单。