zoukankan      html  css  js  c++  java
  • Android theme应用主题实现

    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();
       }
      }

     }
    }


  • 相关阅读:
    中高级PHP程序员应该掌握哪些技术
    如何在FOXMAIL添加网易邮箱
    subline text 3快捷键
    【sublime】sublime Text 3 javaScript代码自动提示插件&安装步骤 &启动Debug模式
    PHPStorm常用快捷键
    怎么样快速修改HOSTS文件?让火绒等小工具来帮忙
    windows系统 右键新建菜单添加新建php文件
    给初学编程的人的干货
    安装Adobe Dreamweaver CC时出现安装失败及解决方法
    win10系统每次打开软件都会弹出账户控制如何解决
  • 原文地址:https://www.cnblogs.com/lechance/p/4373224.html
Copyright © 2011-2022 走看看