网易云音乐、手机QQ的换肤是怎么做到的
对了,还有一个比较重要的方法忘了讲 这个方法就是恢复到系统的默认主题,原理和load都差不多,实现还简单了很多。SkinManager这个类就说这么多,详细实现请到源码中去查看,很多地方我都给了注释。 我们再来看看SkinInflaterFactory,在这里面主要就是做一些填充View相关的一些工作。我实现的是LayoutInflaterFactory这个接口而不是文章之前提到的LayoutInflater.Factory这个接口是因为这里需要与AppCompatActivity兼容,如果你还是用之前的那个就会出现一些错误,反正我刚弄的时候是折腾了很久的。不管怎么样原理始终是一样的。SkinInflaterFactory的作用就是去搜集那些有需要响应皮肤更改的View。 我们来看看onCreateView的实现 首先我们先去判断这个当前将要View是否有更改皮肤的需求,如果没有我们就返回默认的实现。如果有,我们就自己去处理 来看看createView方法的实现 看起来很多,其实这个方法就是去动态的去创建View。 下面来看看parseSkinAttr的实现: 这个方法其实就是去搜集View中换肤的时候可以更改的属性,当我们换肤的时候就是去更改的这些属性的值,这里你必须要注意一点,这个属性的值一定要是引用类型的(例如:@color/red),千万不能写死,第二个if的判断就是这个作用。到这里可能你就会有个疑问,我怎么知道哪些属性在换肤的时候需要更改。如果你细心一点肯定注意到了这行代码
这里有个AttrFacory他的作用就是根据属性名,动态的去创建SkinAttr。在AttrFacory中定义了一些类似于这样的常量: 这就是我们换肤的时候可以更改的那些属性。SkinAttr是一个抽象类,比如background就会去创建一个BackgroundAttr,本项目所用到的属性全都在attr包中。SkinAttr是比较灵活的一个地方,如果你有哪个属性在换肤的时候需要更改,你就去实现一个对应的SkinAttr。 在parseSkinAttr这个方法的最后我们将View和SkinAttr封装成了一个SkinItem然后添加到一个集合中去,最后还需注意的是,如果当前皮肤不是默认皮肤,一定要去apply一下,这样做主要是防止换了皮肤启动一些新的页面有可能导致换肤不及时的问题。SkinInflaterFactory这个类里面还提供了动态的添加SkinItem的方法,原理都和这里差不多,我就不过多的去说了。 load包里面的这两个类讲的差不多了,这里看懂了后面的内容也就是小菜一碟了,我相信你看了这里再去看源码一定会轻松地多。 2.base包 可以看见这个包里面肯定就是Activity、Fragment、Application的实现,作用肯定就是封装一些公用的方法和属性在里面。 下面我们一个一个来分析 SkinBaseApplication: 可以看到这里我们对SkinManager做了一些初始化的操作。以后我们有需要皮肤更改需求的应用一定要记得一定要继承于SkinBaseApplication。 SkinBaseActivity 我们来看看其onCreate方法 在这里使用了我们之前自定义的View的InflaterFactory,来替换默认的Factory。记住一定要在super.onCreate(savedInstanceState);这个方法之前调用。SkinBaseActivity里面还提供了动态添加可以响应皮肤更改需求的View的相关方法。当然需要响应换肤更改的Activity都需要继承SkinBaseActivity。详细实现请看源码。 SkinBaseFragment 这个和SkinBaseActivity的思想差不多。具体实现看源码,这里我只是给大家提供这个换肤框架的思想,让大家在看源码的时候更轻松。 这个框架就介绍到这,下面我们来看看怎么去使用。 在使用的时候一定要记得要Activity要去继承于SkinBaseActivity,Fragment要继承于SkinBaseFragment,Application要继承于SkinBaseApplication。当然把这个框架做为你的项目依赖项肯定是必不可少的。为了Demo的简单,这里我只使用了下面三个颜色作为可以换肤的资源,当然如果你想要使用drawable文件也是可以办到的,前提是你一定要把这个Demo看懂。 (编辑:威海站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |