Android 反射实战 - 更换APP皮肤<1>
来源:互联网 发布:有趣的名字知乎 编辑:程序博客网 时间:2024/06/05 05:28
Android 动态更换APP皮肤,个人感觉更多的是开发者对View理解能力,以及Activity等这种容器是如何加载各种视图view的过程,这个view包括系统UI,自定UI等view.这个地方首先就需要先熟悉Factory这个接口,看一看下面做一个测试工程:
<1> : 新建一个Android 工程项目,目录树如下:
<2> : OneplusFactoryImpl.java 类程序如下:
/** * */package impl;import android.content.Context;import android.util.AttributeSet;import android.util.Log;import android.view.LayoutInflater.Factory;import android.view.LayoutInflater;import android.view.View;/** * @author zhibao.liu * @date 2015-12-8 * @company : oneplus.Inc */public class OneplusFactoryImpl implements Factory { private final static String TAG="oneplus"; /* * (non-Javadoc) * * @see android.view.LayoutInflater.Factory#onCreateView(java.lang.String, * android.content.Context, android.util.AttributeSet) */ @Override public View onCreateView(String name, Context context, AttributeSet attrs) { // TODO Auto-generated method stub View view = createView(context, name, attrs); return null; } private View createView(Context context, String name, AttributeSet attrs) { View view = null; Log.i(TAG,"create name : " + name); try { if (-1 == name.indexOf('.')) { if ("View".equals(name)) { view = LayoutInflater.from(context).createView(name, "android.view.", attrs); } if (view == null) { view = LayoutInflater.from(context).createView(name, "android.widget.", attrs); } if (view == null) { view = LayoutInflater.from(context).createView(name, "android.webkit.", attrs); } } else { view = LayoutInflater.from(context).createView(name, null, attrs); } } catch (Exception e) { Log.i(TAG, "error while create " + name + " : " + e.getMessage()); view = null; } return view; }}
做一个实现factory接口的类.
<2> : 再新建OneplusBaseActivity.java:
/** * */package com.oneplus.base;import impl.OneplusFactoryImpl;import java.lang.reflect.Field;import android.app.Activity;import android.os.Bundle;import android.view.LayoutInflater;/** * @author zhibao.liu * @date 2015-12-8 * @company : oneplus.Inc */public class OneplusBaseActivity extends Activity { private OneplusFactoryImpl mFactory; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); try { Field field = LayoutInflater.class.getDeclaredField("mFactorySet"); field.setAccessible(true); try { field.setBoolean(getLayoutInflater(), false); mFactory = new OneplusFactoryImpl(); getLayoutInflater().setFactory(mFactory); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } catch (NoSuchFieldException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
<3> : OneplusFactoryActivity主类继承上面的基类:
package com.oneplus.factoryimplapp;import com.oneplus.base.OneplusBaseActivity;import android.os.Bundle;import android.app.Activity;import android.view.Menu;/** * *//** * @author zhibao.liu * @date 2015-12-8 * @company : oneplus.Inc */public class OneplusFactoryActivity extends OneplusBaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.oneplus_factory); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.oneplus_factory, menu); return true; } }
然后运行上面程序,结果如下:
一眼看不出来,但是仔细看一下,这个APP所有继承OneplusBaseActivity基类用到的UI信息都包含在里面了,设置包括状态栏.如果还不能够立即,我们在主类的布局增加一个上面没有的一个View,如果Button UI :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".OneplusFactoryActivity" > <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <Button android:id="@+id/button" android:layout_below="@id/text" android:text="hello" android:layout_width="wrap_content" android:layout_height="wrap_content"/></RelativeLayout>
截取其中一部分结果如下:
也就是说,通过上面的方法,在实现Factory接口的类中,可以获取出所有APP中包含的所有UI的种类和属性,我们获取了他们信息,就可以在APP启动的时候,获取并且保存起来,一边供后面获取资源后对所有UI的属性进行动态的更新替换.
0 0
- Android 反射实战 - 更换APP皮肤<1>
- Android 反射实战 - 更换APP皮肤<2>
- Android 反射实战 - 更换APP皮肤<3>
- Android爱读app开发记录之三---皮肤更换
- android----------更换皮肤
- Android更换皮肤
- Android更换皮肤解决方案
- Android 皮肤的更换
- Android实现更换皮肤功能
- android 更换皮肤(主题)
- Android实现更换皮肤功能
- android应用与系统的皮肤更换--1
- Android应用实现更换皮肤功能
- 轻松实现Android 更换皮肤(主题)
- 轻松实现Android 更换皮肤(主题)
- Android 更换皮肤思路及解决方案
- 轻松实现Android 更换皮肤(主题)
- 轻松实现Android更换皮肤(主题)
- 【Java编程】使用增强for循环和迭代器遍历Map集合
- js学习总结
- 前端知乎:关于阮一峰博客《学习Javascript闭包》章节中最后两个思考题
- 【Android】Facebook 登陆APP ID获取 android hash key获取,development/ release
- DB2 detch分区
- Android 反射实战 - 更换APP皮肤<1>
- VS2010为所有的工程配置lib和include路径
- 倒计时自动关闭弹出窗口
- <<UNIX环境高级编程>>随书代码的打开方式
- 认识DOM的三大节点:元素节点,文本节点,属性节点以及nodeName,nodeType,nodeValue的区别
- iOS - 断言处理与调试
- VC++中的通知消息
- 结构(公有类)的运算符重载
- ORACLE表空间的创建修改删除