Android APP怎么换肤
这篇文章主要讲解了“Android APP怎么换肤”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Android APP怎么换肤”吧!
背景需求
目前Android APP
换肤大体可分为两大类:
两套主题的切换(比如白天/黑夜),使用一个开关按钮进行切换。
多套主题在线下载并更新。
第一种的实现基本上使用设置本地Theme
来操作,即将所有的资源打包到APP
中,并且根据主题进行切换。 第二种不可能使用第一种的实现方式,因为将所有资源都打包到APP
中缺乏灵活性,不利于活动的更新,并且也会使得apk
包的体积变大。所有第二种的实现必须是支持线上下载的。
方案选择
配合产品的需求并且能实现换肤的灵动性,我们选择上述的第二种方案。经过之前的Android
和IOS
成员小组讨论,统一觉得可以采用下载压缩包,并通过解析压缩包读取资源进行替换。
压缩包下载下来后怎么读取资源?这里有两种方式:
将下载的皮肤包进行解压缩并且通过文件流的方式读取里面的图片资源、文件资源。
将下载的皮肤包加载到
assetManager
管理器中,并通过该管理器新建一个Resource
对象,需要换肤的控件通过Resource
对象进行读取资源。
第一种方式需要手动开启文件流,并且不同的文件流有不同的文件流方式,比如图片、文本文件等,还有不同设备由于分辨率加载的资源是不同的,如何合理地去选择合适的资源去加载也是一个需要解决的问题。
第二种方式需要将皮肤包加载到assetManager
管理器,assetManager
管理器新生成的Resource
对象和我们主工程的Resource
对象是相同类的不同对象,可以使用我们熟悉的方式去加载资源(如resource.getColor
,resource.getDrawable
等)。
基于上述两种加载资源的方式,这里选择第二种方式进行资源的加载与读取。
具体实施
将所需的皮肤包通过网络下载到本地,这里的皮肤包是一个apk
文件,为了让apk
包足够小,里面只包含资源文件。可能有多个皮肤包,比如theme1.skin
,theme2.skin
......
通过后台获取需要加载的皮肤包的名字,如theme1.skin,通过调用AssetManager对象的addAssetPath方法并生成一个新的Resource对象,如下代码:
AssetManager assetManager = AssetManager.class.newInstance(); //由于addAssetPath()这个方法被隐藏掉了,所以不能直接使用对象直接访问, //这里使用了反射的方式,作用是将该皮肤包加入到asset管理器中 Method addAssetPath = assetManager.getClass().getMethod("addAssetPath" , String.class); addAssetPath.invoke(assetManager, skinPath); Resources skinResource = new Resources( assetManager, superRes.getDisplayMetrics(), superRes.getConfiguration());
自定义一个InflaterFactory
的子类,SkinInflaterFactory
,重写onCreateView(View, String, Context, AttributeSet)
方法,对于需要换肤的控件进行属性的解析与存储,然后对这些换肤的控件去第二步的Resource
对象中加载资源并设置到这些控件中。
在BaseActivity
的onCreate
方法新建SkinInflaterFactory
对象,并将该SkinInflateFactory
对象设置给Activity
的LayoutInflater
对象,如下代码:
protected void onCreate(@Nullable Bundle savedInstanceState) { mSkinInflaterFactory = new SkinInflaterFactory(); LayoutInflaterCompat.setFactory( getLayoutInflater(), mSkinInflaterFactory); super.onCreate(savedInstanceState); }
流程图
其他问题
如何支持控件点击后触发不同的业务流程?
可以通过自定义一个属性,如skin:click="@string/clickAction"
,主工程的clickAction="muapp://app/testDefault"
,皮肤包里的clickAction="muapp://app/testClick"
,通过目前项目中的路由机制触发不同的跳转动作。比如说上述默认的跳转是跳转到主工程(app
为module
名)的TestDefaultAction
(注解actionName="testDefault"
)类的invoke
方法中,而更改后会跳转到主工程(app
为module
名)的TestClickAction
(注解actionName="testClick"
)类的invoke
方法中。
2、如何支持控件的不同行为方式?例如不同的动画效果等
这个问题和第一个问题的处理方式的类似的,同样可以通过主工程和皮肤包不同的tag
(String
文案)处理不同的行为方式。
3、如何处理自定义View
的换肤需求?
可以添加一个方法,将自定义View需要换肤的属性名(如background
),属性值(如background
对应的图片的资源ID
)传递到方法中,然后去皮肤包的Resource
对象中寻找是否有相应的可替换的皮肤或者可替换的行为。
感谢各位的阅读,以上就是“Android APP怎么换肤”的内容了,经过本文的学习后,相信大家对Android APP怎么换肤这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341