前言:
此次修改的系统控件主要包含AlertDialog、Seekbar、switch、Actionbar。修改系统控件可以通过两种方案:一、修改系统的主题样式以及里面的属性值;二、重新定义新的java文件,在布局中引用自定义的控件。各自的优缺点:
方案一:难度小,但牵扯的范围很广,具有局限性(只是修改UI,不能修改功能),因为需要让每个apk生效,就需要让每个apk继承新修改的系统主题样式,而且为了不影响原始的主题样式,最好是新增一个;
方案二:难度大,毕竟要重新复写控件里面的绘制或者布局过程,但具有使用方便、影响小和没有局限性的特点。
本篇先讲解方案一,方案二在下一篇讲解。先大概了解下与四个控件相关的样式属性:
备注:有些从名字就能理解相关的意思。
方法一:只修改系统的主题样式里面的属性及布局
首先我们简单了解下android系统中主题样式的用途及牵扯到的知识点。Android中弄出主题样式的目的:其实是将布局特性与java文件分离,使大家可以很方便的修改布局特性和样式,从而达到不同场景下的需求。
然后了解下主题相关的基础知识点:
frameworks\base\core\res\res\values\ themes_material.xml
frameworks\base\core\res\res\values\ styles_material.xml
4. 主题theme与样式style的区别:主题是大的集合,主要针对apk;style是针对控件的属性集合
5.Style中各个属性值得定义可以参考这边博客:https://www.cnblogs.com/whoislcj/p/5711001.html
6.attrs.xml文件是定义属性,有些需要给外界用的主题或者布局id值都需要在public.xml中定义,有些在java文件中用到的图片 名需要在symbols.xml中添加声明。每次添加这些后,需要用make update-api更新进current.xml(最后出文件也要推送到服务器)
7.如果要修改theme中的属性值,一定要注意此值是否与其他属性有关系,因为android中其他属性会重复利用基础属性值,所以在framework目录下搜索即可。
8.如何判断主题或者样式下的属性值是与控件有关系呢?可以去控件的java文件中找,比如switch控件,swtich.java中都会通过类似于mShowText=a.getBoolean(com.android.internal.R.styleable.Switch_showText,true)方式于属性android:showText关联,注意:在java文件中Switch下的showText属性是这样表示的Switch_showText,他们之间用下划线连接的。
9.theme或者style也有继承,其继承分为隐世继承或者显示继承:隐世继承就是点前面的为父,例如:Widget.Material.CompoundButton.Switch的父样式为Widget.Material.CompoundButton;显示继承就是有parent=,例如:
10.很多控件是继承自View,而View定义了基础的paddingLeft、paddingTop等属性,那么就算在已经有的主题样式没有用,但控件其实都可以用的,我们可以在其样式下面添加。比如:
里面没有paddingLeft,但我们可以在里面添加
通过上面几点大概明白android系统层中主题样式的相关知识,现在我们要做的:(1)我们要改的控件样式是什么?(2)样式的各个属性是控制的什么?
系统控件的样式需要去对应的java文件中寻找,比如switch控件,就去switch.java中的public Switch(Context context, AttributeSet attrs)中就有com.android.internal.R.attr.switchStyle,因此在主题文件themes_material.xml中样式属性为switchStyle,也就是:
Widget.Material.CompoundButton.Switch中就是switch控件的虽有属性集合,我们只需要进去覆盖修改其属性就行。其控件属性有:
//圆圈圈图案
//滑动的轨道图案
//圈圈里面的字体控制
//点击效果
//switch可以在圆圈圈上显示文字,这就是开关
这些属性值有的在switch.java中用到,有的没有用到,如果没有想要的属性,就需要去父样式Widget.Material.CompoundButton中找。找到这些属性值,然后修改即可达到目的。当然里面牵扯到点击效果或动画,可以参考博客:
https://blog.csdn.net/harvic880925/article/details/50995268
https://www.cnblogs.com/MianActivity/p/5867776.html
备注:
(1)在控件中可以覆盖主题或者样式,因为布局中样式级别比主题中的级别高,例如:
在布局中的控件中添加style=”?attr/actionBarStyle”或者android:theme=”?attr/actionBarTheme”就会覆盖theme定义的属性
(2)直接在控件里面调用属性覆盖,例如:
android:layout_height="wrap_content"
android:thumb="@color/colorAccent" />
里面的android:thumb属性就覆盖了theme中定义的属性。
(3)在系统自定义主题后,apk里面继承后,发现不生效,可能是apk里面继承时又覆盖了。例如:
其中Theme.SettingsBase是apk的application继承的主题;Theme.DeviceDefault.Settings是系统层的主题,所以前面需要加上@android:style;此主题就覆盖了actionBarStyle值。
总结
可以通过修改系统属性(里面含布局)达到修改控件UI的目的,但需要弄清楚控件与哪些样式或者属性相关,布局、样式直接不冲突。所以采取此方法需要修改:(毕竟现在都是android5.0以上,所以修改的文件带有material字样)
注意:采取此方法修改系统的控件,也是因为功能位置不变的条件下,只是修改UI样式;如果功能或者位置变了,就需要采取开头讲的方法二。最后放上一个简单的例子——Switch控件的修改样例(没牵扯到public.xml和symbol.xml):
(1)themes_material.xml中新增自定义主题(隐式继承):
(2)在styles_material.xml中定义Widget.Material.CompoundButton.Switch.Prize:
(3)在资源文件drawable中添加prize_switch_track_material和prize_switch_thumb_material_anim,并修改形状动画,点击等效果。
(4)在colors_material.xml和dimens_material.xml中添加尺寸和颜色。
未完待续。。。。