Android skin replacement solution and android Solution

Source: Internet
Author: User
Tags getcolor

Android skin replacement solution and android Solution
Android skin replacement solution

Reprinted with the source: IT_xiao xiaowu

This blog will share with you a Demo about Android app skin replacement. You can go to my github to download the demo. In the future, the Code involved in the blog will be uploaded to github for unified management.
Github address: https://github.com/devilWwj/Android-skin-update

Ideas

What is the skin replacement function generally?
Elements include background color, font color, image, layout, and so on.

We know that there are Theme and style in Android, theme is for the whole activity, and style can be used for the specified control. If there are few replacements, you can do it in the app, but if you need to do it dynamically, you can choose the following idea:
Separate the app and skin, and make the skin into an apk, which can be used as a plug-in for the app. This allows you to download the skin online and change the skin dynamically.

In the demo below, Xiao Wu created a res project and provided a colors. xml project, in which the background color and button color are specified:

<?xml version="1.0" encoding="utf-8"?><resources>    <color name="day_btn_color">#E61ABD</color>    <color name="day_background">#38F709</color>    <color name="night_btn_color">#000000</color>    <color name="night_background">#FFFFFF</color></resources>

There is no logic code in it, just a resource file. Then we export it to the skin.apk file and copy it to the assets of the target project.

Because this operation does not involve downloading skin, you can directly put it in the assets directory, and then copy the apk file under assets to the SD card in the program.
Provide a skin Package Manager in the program

Package com. devilwwj. skin; import java. io. file; import java. io. fileNotFoundException; import java. io. fileOutputStream; import java. io. IOException; import java. io. inputStream; import java. lang. reflect. method; import android. content. context; import android. content. pm. packageInfo; import android. content. pm. packageManager; import android. content. res. assetManager; import android. content. res. resources; import androi D. OS. asyncTask;/*** skin Package Manager ** @ author devilwwj **/public class SkinPackageManager {private static SkinPackageManager mInstance; private Context mContext; /*** current resource package name */public String mPackageName;/*** skin resource */public Resources mResources; public SkinPackageManager (Context mContext) {super (); this. mContext = mContext;}/*** obtain the singleton ** @ param mContext * @ return */public static SkinPackageMan Ager getInstance (Context mContext) {if (mInstance = null) {mInstance = new SkinPackageManager (mContext);} return mInstance ;} /*** copy the apk from assets to sd ** @ param context * @ param filename * @ param path * @ return */public boolean copyApkFromAssets (Context context, String filename, string path) {boolean copyIsFinish = false; try {// enable the input stream InputStream of assets is = context. getAssets (). open (filena Me); File file = new File (path); // create a new file. createNewFile (); FileOutputStream fos = new FileOutputStream (file); byte [] temp = new byte [1024]; int I = 0; while (I = is. read (temp)> 0) {fos. write (temp, 0, I); // write to file} fos. close (); is. close (); copyIsFinish = true;} catch (FileNotFoundException e) {e. printStackTrace ();} catch (IOException e) {e. printStackTrace ();} return copyIsFinish; }/*** Asynchronously load Skin Resources ** @ param dexPath * The Skin Resources to be loaded * @ param callback * callback interface */public void loadSkinAsync (String dexPath, final loadSkinCallBack callback) {new AsyncTask <String, Void, Resources> () {@ Override protected void onPreExecute () {super. onPreExecute (); if (callback! = Null) {callback. startloadSkin () ;}@override protected Resources doInBackground (String... params) {try {if (params. length = 1) {// String dexPath_tmp = params [0]; // obtain Package Manager PackageManager mpm = mContext. getPackageManager (); // obtain the package information PackageInfo mInfo = mpm. getPackageArchiveInfo (dexPath_tmp, PackageManager. GET_ACTIVITIES); mPackageName = mInfo. packageName; // AssetManager instance AssetManager SetManager = AssetManager. class. newInstance (); // call addAssetPath Method addAssetPath = assetManager through reflection. getClass (). getMethod ("addAssetPath", String. class); addAssetPath. invoke (assetManager, dexPath_tmp); // obtain the resource instance Resources superRes = mContext. getResources (); // instantiate the skin resource Resources skinResource = new Resources (assetManager, superRes. getDisplayMetrics (), superRes. getConfiguration (); // Save the resource path Sk InConfig. getInstance (mContext ). setSkinResourcePath (dexPath_tmp); return skinResource ;}} catch (Exception e) {return null;} return null ;}@ Override protected void onPostExecute (Resources result) {super. onPostExecute (result); mResources = result; // The callback method if (callback! = Null) {if (mResources! = Null) {callback. loadSkinSuccess ();} else {callback. loadSkinFail () ;}}}cmd.exe cute (dexPath);} public static interface loadSkinCallBack {public void startloadSkin (); public void loadSkinSuccess (); public void loadSkinFail ();}}

The ingress path. For details, refer to the code.

We use the method provided above in the Activity interface:

Package com. devilwwj. skin; import android. app. activity; import android. content. res. resources; import android. OS. bundle; import android. OS. environment; import android. util. log; import android. view. view; import android. view. view. onClickListener; import android. widget. button; import android. widget. textView; import com. devilwwj. skin. skinPackageManager. loadSkinCallBack;/*** function: Switch the skin * @ author devilwwj **/public Class MainActivity extends Activity implements OnClickListener, ISkinUpdate {private static final String APK_NAME = "skin.apk"; private static final String DEX_PATH = Environment. getExternalStorageDirectory (). getAbsolutePath () + "/skin.apk"; private Button dayButton; private Button nightButton; private TextView textView; private boolean nightModel = false; @ Override protected void onCreate (Bundl E savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); dayButton = (Button) findViewById (R. id. btn_day); nightButton = (Button) findViewById (R. id. btn_night); textView = (TextView) findViewById (R. id. text); // copy the apk file to the SD card SkinPackageManager. getInstance (this ). copyApkFromAssets (this, APK_NAME, DEX_PATH) ;}@ Override protected void onResume () {super. onResum E (); if (SkinPackageManager. getInstance (this). mResources! = Null) {updateTheme () ;}@ Override public void onClick (View v) {switch (v. getId () {case R. id. btn_day: Maid = false; loadSkin (); break; case R. id. btn_night: nightModel = true; loadSkin (); break; default: break;}/*** load skin */private void loadSkin () {SkinPackageManager. getInstance (this ). loadSkinAsync (DEX_PATH, new loadSkinCallBack () {@ Override public void startloadSkin () {Log. d ("xiaowu", "startloadSkin") ;}@ Override public void loadSkinSuccess () {Log. d ("xiaowu", "loadSkinSuccess"); // update the topic updateTheme () ;}@ Override public void loadSkinFail () {Log. d ("xiaowu", "loadSkinFail") ;}}) ;}@ Override public void updateTheme () {Resources mResource = SkinPackageManager. getInstance (this ). mResources; if (nightModel) {// if it is in the dark night mode, the theme int id1 = mResource of the dark night is loaded. getIdentifier ("maid", "color", "com. devilwwj. res "); nightButton. setBackgroundColor (mResource. getColor (id1); int id2 = mResource. getIdentifier ("maid", "color", "com. devilwwj. res "); nightButton. setTextColor (mResource. getColor (id2); textView. setTextColor (mResource. getColor (id2);} else {// if it is in daytime mode, load the daytime topic int id1 = mResource. getIdentifier ("day_btn_color", "color", "com. devilwwj. res "); dayButton. setBackgroundColor (mResource. getColor (id1); int id2 = mResource. getIdentifier ("day_background", "color", "com. devilwwj. res "); dayButton. setTextColor (mResource. getColor (id2); textView. setTextColor (mResource. getColor (id2 ));}}}

We can save a mode, such as the Night and day mode. Each start will display the skin in the previous mode. We can see that the id of the specified resource is obtained by calling the getIdentifier method. name is the name specified in the resource file.

Finally, you can run the following process on your own:
1. Export the res apk File
2. copy to the assets Directory of the Target Project
3. view the skin Switching Effect

Reference blog: http://blog.csdn.net/yuanzeyao/article/details/42390431

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.