Android Replacement Skin Solution

Source: Internet
Author: User
Tags getcolor

Android Replacement Skin Solution

Reprint please indicate source: It_xiao Witch

This blog to share with you about the Android application skin-changing demo, you can go to my github to download the demo, the post-related code will be uploaded to GitHub unified management.
GitHub Address: Https://github.com/devilWwj/Android-skin-update

Ideas

What does the skin changing function usually have?
Elements usually have background color, font color, picture, layout, etc.

We know that there are themes in Android theme and Style,theme are for the entire activity, and the style can be used for the specified control, if a relatively small number of substitutions can be done within the app, but if you need to do it dynamically, you can choose the following idea:
Separate the app from the skin, make the skin an apk, and use it as a plugin for the app, so you can download the skins online and change the skin dynamically.

Below this demo, the wizard is built a res project, simply provides a colors.xml, which specifies the background color and button color:

<?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, just provide the resource file, then we export to skin.apk file, copied to the target project's assets.

Because this does not involve the download of the skin this operation, so directly into the assets directory, and then in the program to copy the assets apk file into the SD card.
Provide a skin Pack manager in the program

 PackageCom.devilwwj.skin;ImportJava.io.File;ImportJava.io.FileNotFoundException;ImportJava.io.FileOutputStream;ImportJava.io.IOException;ImportJava.io.InputStream;ImportJava.lang.reflect.Method;ImportAndroid.content.Context;ImportAndroid.content.pm.PackageInfo;ImportAndroid.content.pm.PackageManager;ImportAndroid.content.res.AssetManager;ImportAndroid.content.res.Resources;ImportAndroid.os.AsyncTask;/** * Skin Pack Manager * * @author DEVILWWJ * * */ Public  class skinpackagemanager {    Private StaticSkinpackagemanager minstance;PrivateContext Mcontext;/** * Current Resource Bundle name */     PublicString Mpackagename;/** * Skin resources * *     PublicResources mresources; Public Skinpackagemanager(Context Mcontext) {Super(); This. Mcontext = Mcontext; }/** * Get a single example * * @param mcontext * @return * *     Public StaticSkinpackagemanagergetinstance(Context Mcontext) {if(Minstance = =NULL) {minstance =NewSkinpackagemanager (Mcontext); }returnMinstance; }/** * Copy apk into SD from assets * * @param context * @param filename * @param Path * @return * /     Public Boolean copyapkfromassets(context context, string filename, string path) {BooleanCopyisfinish =false;Try{//Open the assets input streamInputStream is = Context.getassets (). open (filename); File File =NewFile (path);//Create a new fileFile.createnewfile (); FileOutputStream fos =NewFileOutputStream (file);byte[] temp =New byte[1024x768];inti =0; while((i = is.read (temp)) >0) {Fos.write (temp,0+ N);//write to file} fos.close ();            Is.close (); Copyisfinish =true; }Catch(FileNotFoundException e)        {E.printstacktrace (); }Catch(IOException e)        {E.printstacktrace (); }returnCopyisfinish; }/** * Load Skin Resources Asynchronously * * @param Dexpath * Required skin resources to load * @param Callback * Callback interface * /     Public void Loadskinasync(String Dexpath,FinalLoadskincallback callback) {NewAsynctask<string, Void, resources> () {@Override            protected void OnPreExecute() {Super. OnPreExecute ();if(Callback! =NULL) {Callback.startloadskin (); }            }@Override            protectedResourcesDoinbackground(String ... params) {Try{if(Params.length = =1) {//String dexpath_tmp = params[0];//Get Package ManagerPackagemanager MPM = Mcontext.getpackagemanager ();//Get package InfoPackageInfo mInfo = Mpm.getpackagearchiveinfo (dexpath_tmp, packagemanager.get_activities); Mpackagename = Minfo.packagename;//Assetmanager instancesAssetmanager Assetmanager = Assetmanager.class. newinstance ();//Call the Addassetpath method by reflectionMethod Addassetpath = Assetmanager.getclass (). GetMethod ("Addassetpath", String.class); Addassetpath.invoke (Assetmanager, dexpath_tmp);//Get resource instancesResources superres = Mcontext.getresources ();//Instantiate skin resourcesResources Skinresource =NewResources (Assetmanager, Superres.getdisplaymetrics (), Superr Es.getconfiguration ());//Save resource PathSkinconfig.getinstance (Mcontext). Setskinresourcepath (DEXPATH_TMP);returnSkinresource; }                }Catch(Exception e) {return NULL; }return NULL; }@Override            protected void OnPostExecute(Resources result) {Super. OnPostExecute (Result); Mresources = result;//Execute callback method here                if(Callback! =NULL) {if(Mresources! =NULL) {callback.loadskinsuccess (); }Else{Callback.loadskinfail ();    }}}}.execute (Dexpath); } Public Static  interface loadskincallback {         Public void Startloadskin(); Public void loadskinsuccess(); Public void Loadskinfail(); }}

The focus is on this class, which provides an asynchronous way to manipulate packages and asset, where the reflection mechanism is used, and reflection calls Addassetpath to add assets path, which is the path of our skin.apk. See the code for specifics.

We use the methods provided above in the activity interface:

 PackageCom.devilwwj.skin;Importandroid.app.Activity;ImportAndroid.content.res.Resources;ImportAndroid.os.Bundle;ImportAndroid.os.Environment;ImportAndroid.util.Log;ImportAndroid.view.View;ImportAndroid.view.View.OnClickListener;ImportAndroid.widget.Button;ImportAndroid.widget.TextView;ImportCom.devilwwj.skin.SkinPackageManager.loadSkinCallBack;/** * Function: Toggle skin * @author DEVILWWJ * */ Public  class mainactivity extends Activity  implements  Onclicklistener, iskinupdate {    Private Static FinalString Apk_name ="skin.apk";Private Static FinalString Dex_path = environment. getExternalStorageDirectory (). GetAbsolutePath () +"/skin.apk";PrivateButton Daybutton;PrivateButton Nightbutton;PrivateTextView TextView;Private BooleanNightmodel =false;@Override    protected void onCreate(Bundle 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 cardSkinpackagemanager.getinstance ( This). Copyapkfromassets ( This, Apk_name, Dex_path); }@Override    protected void Onresume() {Super. Onresume ();if(Skinpackagemanager.getinstance ( This). mresources! =NULL) {updatetheme (); }    }@Override     Public void OnClick(View v) {Switch(V.getid ()) { CaseR.id.btn_day:nightmodel =false; Loadskin (); Break; CaseR.id.btn_night:nightmodel =true; Loadskin (); Break;default: Break; }    }/** * Loading skin * *    Private void Loadskin() {skinpackagemanager.getinstance ( This). Loadskinasync (Dex_path,NewLoadskincallback () {@Override                     Public void Startloadskin() {LOG.D ("Xiaowu","Startloadskin"); }@Override                     Public void loadskinsuccess() {LOG.D ("Xiaowu","Loadskinsuccess");//Then update the theme hereUpdatetheme (); }@Override                     Public void Loadskinfail() {LOG.D ("Xiaowu","Loadskinfail");    }                }); }@Override     Public void Updatetheme() {Resources mresource = skinpackagemanager.getinstance ( This). Mresources;if(Nightmodel) {//If it is night mode, load the theme of the night            intID1 = Mresource.getidentifier ("Night_btn_color","Color","Com.devilwwj.res"); Nightbutton.setbackgroundcolor (Mresource.getcolor (ID1));intId2 = Mresource.getidentifier ("Night_background","Color","Com.devilwwj.res");            Nightbutton.settextcolor (Mresource.getcolor (ID2));        Textview.settextcolor (Mresource.getcolor (ID2)); }Else{//If it is daylight mode, load the daytime theme            intID1 = Mresource.getidentifier ("Day_btn_color","Color","Com.devilwwj.res"); Daybutton.setbackgroundcolor (Mresource.getcolor (ID1));intId2 = Mresource.getidentifier ("Day_background","Color","Com.devilwwj.res");            Daybutton.settextcolor (Mresource.getcolor (ID2));        Textview.settextcolor (Mresource.getcolor (ID2)); }    }}

We can save a pattern, such as the night daytime mode, each time it starts to display the skin in the previously saved mode. We can see that the above is the name that we specify in the resource file by calling the Getidentifier method to get the specified resource id,name.

Finally, you run through the process yourself:
1. Export the res apk file
2. Copy to the assets directory of the target project
3. View the effect of switching skins

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

Android Replacement Skin Solution

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.