Android theme應用主題實現,androidtheme

來源:互聯網
上載者:User

Android theme應用主題實現,androidtheme
Android實現應用Theme的方式是通過apk來實現的。下面是一個demo。

 
1.首先必須建立一個apk,類似的外掛程式,然後在該apk的AndroidManifest.xml檔案的application加上一個meta-data。這個是下一步尋找是否是自己的外掛程式的apk做一個標記。

<meta-data android:name="skin_demo2_plugin" android:value="com.example.skindemo2.icon"/>

2.在該apk添加一些圖片,也可以用其他(包括style等)這裡主要是為了示範。在該apk的MainActivity定義一個方法。這裡主要為了方便主apk快速調用這個方法。

static int allDrawableId[] = {R.drawable.img_apparel_accessories,R.drawable.img_computers_software
  ,R.drawable.img_electro,R.drawable.img_electronics,R.drawable.img_entertaiment
  ,R.drawable.img_food_beverage,R.drawable.img_kids_baby,R.drawable.img_sport,R.drawable.img_toys_games};
 
 public int getDrawableIdForOtherApp(int position){
  
  if(position < allDrawableId.length){
   return allDrawableId[position];
  }
  return 0; 
 }

3.在主apk中通過讀取所有安裝的應用,通過分析applicationInfo的meta-data,然後判斷是否是自己的外掛程式apk。
 
然後通過context.createPackageContext(packageName,int flag)得到相應外掛程式的context。然後通過類載入器得到MainActivity的class類,然後通過反射得到方法返回的值。然後就可以得到drawable對象。

package com.example.skindemo2;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {

 private Button mSwtichImgBgBtn;
 private ImageView mShowImg;
 private Context context;
 private ArrayList<String> mPluginPackageNameList = new ArrayList<String>();
 private int position = 0;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  context = this;
  mSwtichImgBgBtn = (Button) this.findViewById(R.id.swtichImgBgBtn);
  mSwtichImgBgBtn.setOnClickListener(new View.OnClickListener() {
   
   @Override
   public void onClick(View v) {
    swtichImgUsePlugin();
   }
  });
  mShowImg = (ImageView) this.findViewById(R.id.myShowImg);
  new AsyncTask<Void, Void, Void>() {

   @Override
   protected Void doInBackground(Void... params) {
    findPluginPackageName();
    return null;
   }
   
   @Override
   protected void onPostExecute(Void result) {
    swtichImgUsePlugin();
    super.onPostExecute(result);
   }
  }.execute();

 }

 private void findPluginPackageName() {
  PackageManager pm = context.getPackageManager();
  List<PackageInfo> list = pm.getInstalledPackages(0);//得到所有安裝的apk的PackageInfo
  String meta = null;
  ApplicationInfo aInfo = null;
  for (PackageInfo pi : list) {
   String pkgName = pi.packageName;
   try {
    aInfo = pm.getApplicationInfo(pkgName,
      PackageManager.GET_META_DATA);
   } catch (NameNotFoundException e) {
    e.printStackTrace();
   }
   if (aInfo == null || aInfo.metaData == null)
    continue;
   meta = aInfo.metaData.getString("skin_demo2_plugin");
   if (meta == null || "".equals(meta))
    continue;
   if ("com.example.skindemo2.icon".equals(meta)) {
    //通過meta的值判斷是否是自己的外掛程式apk
    mPluginPackageNameList.add(aInfo.packageName);
   }
  }
 }
 //必須在主線程中操作
 private void swtichImgUsePlugin() {
  //我這裡為了方便直接就取了第一個外掛程式apk資料,實際中是通過使用者選擇的apk來切換
  if (mPluginPackageNameList.size() != 0) {
   try {
    //通過createPackageContext方法得到外掛程式apk的context
    Context otherplusContext = context.createPackageContext(
      mPluginPackageNameList.get(0),
      Context.CONTEXT_INCLUDE_CODE
        | Context.CONTEXT_IGNORE_SECURITY);
    //通過得到外掛程式apk的context類載入器,然後得到MainActvity的類對象
    Class<?> mainClass = otherplusContext
      .getClassLoader()
      .loadClass(mPluginPackageNameList.get(0) + ".MainActivity");
    //通過反射得到相應位置的drawable
    Method m = mainClass.getMethod("getDrawableIdForOtherApp",
      int.class);
    int imgBgId = (Integer) m.invoke(mainClass.newInstance(), position);
    //為了可以迴圈切換img
    if(imgBgId == 0){
      position = 0;
    }else{
      position += 1;
    }
    //得到drawable對象
    Drawable drawable = otherplusContext.getResources()
      .getDrawable(imgBgId);
    mShowImg.setImageDrawable(drawable);
   } catch (Exception e) {
    e.printStackTrace();
   }
  }

 }
}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.