十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
Draw 过程系列文章
宜阳ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为成都创新互联公司的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:13518219792(备注:SSL证书合作)期待与您的合作!
Android 展示之三部曲:
前边我们已经分析了:
这俩最主要的任务是: 确定View/ViewGroup可绘制的矩形区域。
接下来将会分析,如何在这给定的区域内绘制想要的图形。
通过本篇文章,你将了解到:
Android 提供了关于View最基础的两个类:
然而ViewGroup 并没有约定其内部的子View是如何布局的,是叠加在一起呢?还是横向摆放、纵向摆放等。同样的View 也没有约定其展示的内容是啥样,是矩形、圆形、三角形、一张图片、一段文字抑或是不规则的形状?这些都要我们自己去实现吗?
不尽然,值得高兴的是Android已经考虑到上述需求了,为了开发方便已经预制了一些常用的ViewGroup、View。
如:
继承自ViewGroup的子类
继承自View的子类
虽然以上衍生的View/ViewGroup子类已经大大为我们提供了便利,但也仅仅是通用场景下的通用控件,我们想实现一些较为复杂的效果,比如波浪形状进度条、会发光的球体等,这些系统控件就无能为力了,也没必要去预制千奇百怪的控件。想要达到此效果,我们需要自定义View/ViewGroup。
通常来说自定义View/ViewGroup有以下几种:
3 一般不怎么用,除非布局比较特殊。1、2、4 是我们常用的手段,对于我们常说的"自定义View" 一般指的是 4。
接下来我们来看看 4是怎么实现的。
在xml里引用MyView
效果如下:
黑色部分为其父布局背景。
红色矩形+黄色圆形即是MyView绘制的内容。
以上是最简单的自定义View的实现,我们提取重点归纳如下:
由上述Demo可知,我们只需要在重写的onDraw(xx)方法里绘制想要的图形即可。
来看看View 默认的onDraw(xx)方法:
发现是个空实现,因此继承自View的类必须重写onDraw(xx)方法才能实现绘制。该方法传入参数为:Canvas类型。
Canvas翻译过来一般叫做画布,在重写的onDraw(xx)里拿到Canvas对象后,有了画布我们还需要一支笔,这只笔即为Paint,翻译过来一般称作画笔。两者结合,就可以愉快的作画(绘制)了。
你可能发现了,在Demo里调用
并没有传入Paint啊,是不是Paint不是必须的?实际上调用该方法后,底层会自动生成Paint对象。
可以看到,底层初始化了Paint,并且给其设置的颜色为在Java层设置的颜色。
onDraw(xx)比较简单,开局一个Canvas,效果全靠画。
试想,这个Canvas怎么来的呢,换句话说是谁调用了onDraw(xx)。发挥一下联想功能,在Measure、Layout 过程有提到过两者套路很像:
那么Draw过程是否也是如此套路呢?看见了onDraw(xx),那么draw(xx)还远吗?
没错,还真有draw(xx)方法:
可以看出,draw(xx)主要分为两个部分:
不管是A分支还是B分支,都进行了好几步的绘制。
通常来说,单一一个View的层次分为:
后面绘制的可能会遮挡前边绘制的。
对于一个ViewGroup来说,层次分为:
来看看A分支标注的4个点:
(1)
onDraw(canvas)
前面分析过,对于单一的View,onDraw(xx)是空实现,需要由我们自定义绘制。
而对于ViewGroup,也并没有具体实现,如果在自定义ViewGroup里重写onDraw(xx),它会执行吗?默认是不会执行的,相关分析请移步:
Android ViewGroup onDraw为什么没调用
(2)
dispatchDraw(canvas),来看看在View.java里的实现:
发现是个空实现,再看看ViewGroup.java里的实现:
也即是说,对于单一View,因为没有子布局,因此没必要再分发Draw,而对于ViewGroup来说,需要触发其子布局发起Draw过程(此过程后续分析),可以类比事件分发过程View、ViewGroup的处理。感兴趣的请移步:
Android 输入事件一撸到底之View接盘侠(3)
(3)
OverLay,顾名思义就是"盖在某个东西上面",此处是在绘制内容之后,绘制前景之前。怎么用呢?
以上是给一个ViewGroup设置overLay,效果如下:
你可能发现了,这和设置overLay差不多的嘛,实际还是有差别的。在onDrawForeground(xx)里会重新调整Drawable的尺寸,该尺寸与View大小一致,之前给Drawable设置的尺寸会失效。运行效果如下:
可以看出,ViewGroup都被前景盖住了。
再来看看B分支的重点:边缘渐变效果
先来看看TextView 边缘渐变效果:
加上这俩参数。
实际上系统自带的一些控件也使用了该效果,如NumberPicker、YearPickerView
以上是NumberPicker 的效果,可以看出是垂直方向渐变的。
对于View.java 里的onDraw(xx)、draw(xx),ViewGroup.java里并没有重写。
而对于dispatchDraw(xx),在View.java里是空实现。在ViewGroup.java里发起对子布局的绘制。
来看看标记的2点:
(1)
设置padding的目的是为了让子布局留出一定的空隙出来,因此当设置了padding后,子布局的canvas需要根据padding进行裁减。判断标记为:
FLAG_CLIP_TO_PADDING 默认设置为true
FLAG_PADDING_NOT_NULL 只要有padding不为0,该标记就会打上。
也就是说:只要设置了padding 不为0,子布局显示区域需要裁减。
能不能不让子布局裁减显示区域呢?
答案是可以的。
考虑到一种场景:使用RecyclerView的时候,我们需要设置paddingTop = 20px,效果是:RecyclerView Item展示时离顶部有20px,但是滚动的时候永远滚不到顶部,看起来不是那么友好。这就是上述的裁减起作用了,需要将此动作禁止。通过设置:
当然也可以在xml里设置:
(2)
drawChild(xx)
从方法名上看是调用子布局进行绘制。
child.draw(x1,x2,x3)里分两种情况:
这两者具体作用与区别会在下篇文章分析,不管是硬件加速绘制还是软件加速绘制,最终都会调用View.draw(xx)方法,该方法上面已经分析过。
注意,draw(x1,x2,x3)与draw(xx)并不一样,不要搞混了。
用图表示:
View/ViewGroup Draw过程的联系:
一般来说,我们通常会自定义View,并且重写其onDraw(xx)方法,有没有绘制内容的ViewGroup需求呢?
是有的,举个例子,大家可以去看看RecyclerView ItemDecoration 的绘制,其中运用到了ViewGroup draw(xx)、ViewGroup onDraw(xx) 、View onDraw(xx)绘制的先后顺序来实现分割线,分组头部悬停等功能的。
本篇文章基于 Android 10.0
Android中的Selector主要是用来改变控件的背景,可以设置控件不同状态下的背景,如按下,焦点,无焦点,被选中。。。等等
创建selecetor一般放在res的drawable目录下
右击drawable目录,new一个android xml file
填入文件名,选择selector
下面开始写一个按键的按下和正常状态下的背景
?xml version="1.0" encoding="utf-8"?
selector xmlns:android=""
item android:state_pressed="true"
shape
solid android:color="#FF2233"/
/shape
/item
item
shape
solid android:color="#FF6633"/
/shape
/item
/selector
item中state的属性有如下
android:state_pressed 是否按下,如一个按钮触摸或者点击。
android:state_focused 是否取得焦点,比如用户选择了一个文本框。
android:state_hovered 光标是否悬停,通常与focused state相同,它是4.0的新特性
android:state_selected 被选中,它与focus state并不完全一样,如一个list view 被选中的时候,它里面的各个子组件可能通过方向键,被选中了。
android:state_checkable 组件是否能被check。如:RadioButton是可以被check的。
android:state_checked 被checked了,如:一个RadioButton可以被check了。
android:state_enabled 能够接受触摸或者点击事件
android:state_activated 被激活(这个麻烦举个例子,不是特明白)
android:state_window_focused 应用程序是否在前台,当有通知栏被拉下来或者一个对话框弹出的时候应用程序就不在前台了
需要注意的是如果有多个item,那么程序将自动从上到下进行匹配,最先匹配的将得到应用。所以最好把默认的放到最后面
用过Eclipse的同志都知道在Eclipse中鼠标悬停在一个变量,类,方法名当中,其有文档注释的话会弹出一个提示框出来显示文档注释的内容。做Android开发的小伙伴来说,Android studio作为Google的亲儿子更受众多猿青睐,但是刚从Eclipse投靠过来的兄弟来说会有很大的不习惯。快捷键就是其中之一,已习惯Eclipse的鼠标悬停提示注释的人来说,在Android studio默认不显示悬停提示,这也是很大的反感(快捷键可以是f2,也可是Ctrl+ q显示。不过这对电脑配置差一点的同志来说也是挺好的)。其实在Android studio中也可以设置鼠标悬停提示的。setting-General
1、为全面屏设计
由于 MIUI 是覆盖数亿人手机的操作系统,因此 MIUI 的设计变革也将是「渐进式」的。
此次在 MIUI 10 上,部分原本通过虚拟按键操控的功能,都将被手势操作替代,而为了减少用户的上手成本,MIUI 设计团队采用了名为「悬浮球」的提示方式来引导用户,同时为桌面图标增加了动态效果,以此补充操作中缺少的「确认感」。
目前 MIUI 10 已知的手势包括「上滑退出应用」、「从边缘横向长距离滑动并悬停实现应用切换」等。
在页面设计上,MIUI 10 也应用了更多全新元素。比如默认主题与图标都得到了更新,多任务界面采用了「瀑布流」布局,亮度调节与音量调节面板的触摸区域被放大等,在操作逻辑上也得到了一定的简化。
2、「自然」声音系统
小米表示,MIUI 10 希望通过 为用户的耳朵「减负」。
在新系统中,不少机械声效被替换为了大自然的声音——输入音取材于木鱼敲击、删除音取材于沙子;而针对起床铃声和倒计时工具,MIUI 10 则提供了森林、夏夜、海滩、炉火、细雨 5 种「白噪音」,还可以根据天气的变化自动更换设定。
通过 AI 算法,MIUI 10 据称还拥有了智能筛选通知的功能——可以将不必要的通知折叠、通过响铃次数上限将多余的铃声静默、并精简不必要的系统界面音效等。
3、更聪明的「小爱同学」
全新「小爱同学」在 MIUI 10 中获得了「唤醒方式」、「耳语输入」、「AI 训练」、「驾车模式」、「语音全局搜索」等方面的新技能。
「小爱同学」现在可以通过「信息助手按钮」、「长按 Home 键」、「长按电源键」、「语音唤醒」这 4 种方式唤醒;而为了避免在公共场合使用语音助手的尴尬,「小爱同学」据称可以听懂用户更加「轻声细语」的命令。
由于每个人使用语音助手的习惯不同,这次 MIUI 设计团队还为「小爱同学」带来了名为「AI 训练」的新功能,用户可以为「小爱」设定特殊交互,或是教她学会自定义的特殊技能。
使用小爱同学的一个典型场景就是驾车。如果用户开车手忙脚乱时会很容易发生危险。MIUI10 的小爱同学开创性探索驾车模式,让你在开车时替你操作手机。
在语音助手可实现的功能上,「小爱同学」现在也能支持以往更多的第三方应用,目前官方公布的支持名单如下:
● 社交类:微信、QQ、微博
● 音乐电台类:小米音乐、QQ 音乐、酷狗音乐、网易云音乐、蜻蜓 FM、喜马拉雅
● 视频类:小米视频、爱奇艺、腾讯视频、优酷视频
● 地图类:高德地图、百度地图、腾讯地图
● 出行类:滴滴出行、摩拜单车、ofo
● 生活服务类:手机淘宝、京东、大众点评、支付宝
● 系统应用:便签、相机、小米钱包、智能识物、安全中心
4、AI 单摄虚化
MIUI 10 为手机人像模式带来了「AI 单摄虚化」功能。官方表示「基于数十万张照片训练的深度学习算法」,MIUI 10 可以完全依靠算法识别镜头所摄人物的边缘,并完成虚化。
5、AI 预载入和跟手度优化
MIUI 10 新引入的 AI 预加载功能,据称可以根据用户使用习惯,预判用户即将使用的应用,并在后台将其预加载,以此「一定概率」实现 0 秒应用加载时间。
而在界面跟手度方面,小米宣称,MIUI 10 在桌面滑动、浏览照片、浏览网页、浏览微信对话等常用场景上「跟手度全面超越安卓各厂商」。
6、图片的「超清分辨率」优化
超清分辨率是 MIUI 10 上新增的探索型实验室功能,当用户在微信朋友圈或今日头条中点击图片浏览大图时,其 AI 算法会自动优化高宽均在 100px 至 800px 之间的图片,将不清晰的图片处理得更清晰。
7、传送门 2.0
MIUI 10 搭载的「传送门 2.0」功能,据称在可识别的内容上做出了大幅度扩展。根据官方信息,「传送门 2.0」可识别的屏幕内容新增了:
● 国家和行政区域
● 小说
● 酒店
● 旅游景点
● 动植物百科
● 新版火车、飞机等
而在图片识别方面,「传送门 2.0」也将新增以下类目:
● 图片文字提取
● 名片内容
● 植物物种
● 动物品种
● 名人面孔
● 中外名画
● 电影海报
● 书籍封面
8、闪电连接
当 MIUI 10 手机添加一个新的米家智能设备时,系统在扫描到待添加的智能设备后,就自动触发提示弹窗,点击后即可完成对设备的添加。
9、智能家居卡片
MIUI 10 信息助手中新增了智能家居卡片,让用户可以在桌面快速操作常用的智能硬件设备。
10、语音智能场景
MIUI 10 上的「小爱同学」可以直接启动米家智能场景——用户对「小爱同学」说出所设置的场景名, 就能完成较为复杂的智能设备控制。
RecyclerView分组悬浮列表
推荐,个人感觉这个很好用
这个也可以
android:drawable 放一个drawable资源
android:state_pressed 是否按下,如一个按钮触摸或者点击。
android:state_focused 是否取得焦点,比如用户选择了一个文本框。
android:state_hovered 光标是否悬停,通常与focused state相同,它是4.0的新特性
android:state_selected 被选中,它与focus state并不完全一样,如一个list view 被选中的时候,它里面的各个子组件可能通过方向键,被选中了。
android:state_checkable 组件是否能被check。如:RadioButton是可以被check的。
android:state_checked 被checked了,如:一个RadioButton可以被check了。
android:state_enabled 能够接受触摸或者点击事件
android:state_activated 被激活
android:state_window_focused 应用程序是否在前台,当有通知栏被拉下来或者一个对话框弹出的时候应用程序就不在前台了