現在的APP開發,通常會提供APP的換膚功能,網上流傳的換膚代碼和實現手段過於復雜,我把原作者的代碼重新整理抽取出來,轉換成Eclipse項目,重新整理成正確、可直接運行的項目.
代碼運行結果如圖。
假設默認是黃色皮膚:
換膚成紅色:
換膚成綠色:
使用方式:
1,首先要自定義一個Application,在AppTest中就是MyApplication。完成初始化。
1 package zhangphil.apptest; 2 3 import com.zhy.changeskin.SkinManager; 4 5 import android.app.Application; 6 7 public class MyApplication extends Application { 8 @Override 9 public void onCreate() { 10 super.onCreate(); 11 SkinManager.getInstance().init(this); 12 } 13 }
2,把這個MyApplication寫到Androidmanifest.xml里面:
3,在打算實現換膚的activity里面的onCreate()和onDestory()里面添加相應的“注冊”和“注銷”代碼:
1 @Override 2 protected void onCreate(Bundle savedInstanceState) { 3 super.onCreate(savedInstanceState); 4 ... 5 SkinManager.getInstance().register(this); 6 ... 7 } 8 9 @Override 10 protected void onDestroy(){ 11 super.onDestroy(); 12 SkinManager.getInstance().unregister(this); 13 }
本例完整的MainActivity.Java代碼:
1 package zhangphil.apptest; 2 3 import com.zhy.changeskin.SkinManager; 4 5 import android.app.Activity; 6 import android.os.Bundle; 7 import android.view.Menu; 8 import android.view.MenuItem; 9 10 public class MainActivity extends Activity { 11 12 @Override 13 protected void onCreate(Bundle savedInstanceState) { 14 super.onCreate(savedInstanceState); 15 16 SkinManager.getInstance().register(this); 17 18 setContentView(R.layout.activity_main); 19 } 20 21 @Override 22 protected void onDestroy(){ 23 super.onDestroy(); 24 SkinManager.getInstance().unregister(this); 25 } 26 27 @Override 28 public boolean onCreateOptionsMenu(Menu menu) { 29 getMenuInflater().inflate(R.menu.main, menu); 30 return true; 31 } 32 33 @Override 34 public boolean onOptionsItemSelected(MenuItem item) { 35 int id = item.getItemId(); 36 if (id == R.id.red_skin) { 37 SkinManager.getInstance().changeSkin("red"); 38 return true; 39 } 40 41 if (id == R.id.green_skin) { 42 SkinManager.getInstance().changeSkin("green"); 43 return true; 44 } 45 46 if (id == R.id.default_skin) { 47 SkinManager.getInstance().changeSkin("default");; 48 return true; 49 } 50 51 return super.onOptionsItemSelected(item); 52 } 53 }
以上完成后,剩下的就是比較繁瑣和稍微需要理解的難點。
以Android ImageView為例,假設要對某一個ImageView實現一鍵換膚功能,在本例是要將ImageView的src圖片換成相應的皮膚顏色,那么首先需要准備幾套以一個共同前綴名和不同后綴名組成的圖片資源,本例是:
相同的前綴名是skin_img ,不同的后綴名是 green,red,default,后綴名至關重要,后面將以后綴名換膚。中間用連詞符“_”連接起來。
然后在ImageView里面添加tag字段屬性。Tag字段屬性有三部分組成,以本例的ImageView為例,第一部分skin是固定的,不用管。接着就是上面的前綴 skin_img,第三部分是作為ImageView的src為靶子換膚。
1 <ImageView 2 android:id="@+id/image" 3 android:layout_width="wrap_content" 4 android:layout_height="wrap_content" 5 android:layout_centerInParent="true" 6 android:tag="skin:skin_img:src" 7 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定義的相關屬性:
1 <?xml version="1.0" encoding="utf-8"?> 2 <resources> 3 <color name="text_color_red">#ff0000</color> 4 <color name="text_color_green">#00ff00</color> 5 <color name="text_color_default">#ffff00</color> 6 </resources>
本例的換膚在menu菜單里面觸發,就直接以之前定義的ImageView和TextView的不同后綴名:
1 @Override 2 public boolean onOptionsItemSelected(MenuItem item) { 3 int id = item.getItemId(); 4 if (id == R.id.red_skin) { 5 SkinManager.getInstance().changeSkin("red"); 6 return true; 7 } 8 9 if (id == R.id.green_skin) { 10 SkinManager.getInstance().changeSkin("green"); 11 return true; 12 } 13 14 if (id == R.id.default_skin) { 15 SkinManager.getInstance().changeSkin("default");; 16 return true; 17 } 18 19 return super.onOptionsItemSelected(item); 20 }
更為全面的說明不如直接看我寫的AppTest這個項目代碼,項目源代碼例子我盡量寫的比較簡單。
新的github鏈接地址:https://github.com/zhangphil/Android-ChangeSkin