Android官方开发文档Training系列课程中文版:创建自定义View之View的绘制

原文地址:http://android.xsoftlab.net/training/custom-views/custom-drawing.html#draw

自定义View最重要的部分就是它的样子了。自定义View的绘制根据应用的需要或者简单亦或者复杂。这节课的内容涵盖了大多数通用的知识点。

重写onDraw()方法

绘制自定义View很重要的一个步骤就是重写它的onDraw()方法。该方法含有一个Canvas对象作为参数,用来使View绘制它本身的内容。Canvas类定义了用于绘制文本,线条,位图以及许多其它基础的物理图形的方法。你可以在onDraw()方法中使用这些方法来创建属于你自己的UI效果。

在开始任何绘制之前,必须先创建一个Paint对象。后面的部分会讨论Paint的相关知识。

创建绘制对象

android.graphics框架将绘制分为了两块区域:

  • 要绘制什么,由Canvas控制
  • 如何绘制,由Paint控制

举个例子,Canvas提供了用于绘制线条的方法,而Paint则定义了线条的颜色。Canvas拥有绘制矩形的方法,而Paint则定义了是否要使颜色填充这个矩形。简而言之,Canvas定义了你绘制在屏幕上的形状,而Paint则定义了这些形状的颜色、风格以及字体等等。

所以,在开始绘制任何事物之前,你需要先创建一个或多个Paint对象。示例PieChart将这些工作放在了一个名为init的方法中,它由构造方法调用:

private void init() {mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mTextPaint.setColor(mTextColor);if (mTextHeight == 0) {mTextHeight = mTextPaint.getTextSize();} else {mTextPaint.setTextSize(mTextHeight);}mPiePaint = new Paint(Paint.ANTI_ALIAS_FLAG);mPiePaint.setStyle(Paint.Style.FILL);mPiePaint.setTextSize(mTextHeight);mShadowPaint = new Paint(0);mShadowPaint.setColor(0xff101010);mShadowPaint.setMaskFilter(new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL));...

提前创建对象是一项非常重要的优化手段。View会很频繁的绘制,创建绘制对象的开销十分高昂。在onDraw()方法中创建绘制对象会明显的降低应用的性能,并可能会导致UI出现停顿。

处理布局事件

为了可以正确的绘制View,首先需要知道View的尺寸。复杂一点的View经常需要执行多次布局计算。你永远不要假定View的尺寸,就算是只有一款应用使用了你的View。因为APP需要处理不同的屏幕尺寸,不同的屏幕密度,以及在垂直模式及水平模式下不同的高宽比。

尽管View拥有很多测量尺寸的方法,但是绝大多数是不需要重写的。如果View不需要特别控制它的尺寸,你只需要重写一个方法:onSizeChanged().

onSizeChanged()方法会在首次分配尺寸的时候调用,如果尺寸再次变更时则会再次调用。我们在onSizeChanged()方法中计算View的位置、尺寸以及其它任何与尺寸相关的值,而不是在每次绘制的时候重新计算它们。在示例PieChart中,onSizeChanged()方法内部计算了饼图的矩形边框以及文本和其它可视元素的相对位置。

当View被分配了一个尺寸时,布局管理器会假设该尺寸包含了View所有的内边距。所以在计算View的尺寸时要将View的内边距计算在内。下面的代码段展示了PieChart.onSizeChanged()是如何做的:

       // Account for paddingfloat xpad = (float)(getPaddingLeft() + getPaddingRight());float ypad = (float)(getPaddingTop() + getPaddingBottom());// Account for the labelif (mShowText) xpad += mTextWidth;float ww = (float)w - xpad;float hh = (float)h - ypad;// Figure out how big we can make the pie.float diameter = Math.min(ww, hh);

如果你想更精细的控制View布局的参数,请实现onMeasure()方法。这个方法的两个参数都为View.MeasureSpec。它们用于告诉View的父布局希望View是多大,这个View的尺寸是最大值还是只是一个建议值等等。随着优化,这些值被存放在一个被包装后的整型值内,你必须使用View.MeasureSpec的一个静态方法来提取存储在这个整型值内的信息。

下面是onMeasure()方法的一个示例。在这个实现中,PieCart尝试将自己的区域扩大到内部标签的大小。

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// Try for a width based on our minimumint minw = getPaddingLeft() + getPaddingRight() + getSuggestedMinimumWidth();int w = resolveSizeAndState(minw, widthMeasureSpec, 1);// Whatever the width ends up being, ask for a height that would let the pie// get as big as it canint minh = MeasureSpec.getSize(w) - (int)mTextWidth + getPaddingBottom() + getPaddingTop();int h = resolveSizeAndState(MeasureSpec.getSize(w) - (int)mTextWidth, heightMeasureSpec, 0);setMeasuredDimension(w, h);
}

这里有三个非常重要的点需要关注:

  • 这个公式将View的内边距一并计算在内。正如前面所说的,这是View本身的职责。
  • 辅助方法resolveSizeAndState()用于创建最终的宽度值与高度值。这个辅助方法通过比较View的期望值与onMeasure()回调的spec值,最后返回一个适当的View.MeasureSpec值。
  • onMeasure()没有返回值。相反的,该方法通过调用setMeasuredDimension()方法与外界交流。调用这个方法是强制要求的。如果你忽略了这个调用,那么View类会抛出一个运行时异常。

绘制

完成对象创建代码与尺寸测量代码之后,接下来就可以实现onDraw()方法了。每个View的onDraw()方法都不相同,但是它们还是有一些相同特点存在的:

  • 使用drawText()方法绘制文本。通过setTypeface()方法指定字体类型,通过setColor()方法设置文本颜色。
  • 通过drawRect()、drawOval()和drawArc()绘制基础图形。通过setStyle()更改图形是填充模式还是绘制轮廓模式,或者两者都不是。
  • 通过Path类来绘制更加复杂的图形。通过给Path对象添加线条及曲线来定义形状,然后通过drawPath()方法绘制这些形状。只是这些基础形状可以通过setStyle()方法来定义它们的Path风格。
  • 通过创建LinearGradient对象可以定义梯度填充模式。调用setShader()方法来填充形状。
  • 通过drawBitmap()方法绘制位图。

举个例子,下面的代码用来绘制PieChart。它混合使用了文本、线条以及形状。

protected void onDraw(Canvas canvas) {super.onDraw(canvas);// Draw the shadowcanvas.drawOval(mShadowBounds,mShadowPaint);// Draw the label textcanvas.drawText(mData.get(mCurrentItem).mLabel, mTextX, mTextY, mTextPaint);// Draw the pie slicesfor (int i = 0; i < mData.size(); ++i) {Item it = mData.get(i);mPiePaint.setShader(it.mShader);canvas.drawArc(mBounds,360 - it.mEndAngle,it.mEndAngle - it.mStartAngle,true, mPiePaint);}// Draw the pointercanvas.drawLine(mTextX, mPointerY, mPointerX, mPointerY, mTextPaint);canvas.drawCircle(mPointerX, mPointerY, mPointerSize, mTextPaint);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/478969.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 965. 单值二叉树

文章目录1. 题目2. 解题2.1 递归2.2 循环1. 题目 如果二叉树每个节点都具有相同的值&#xff0c;那么该二叉树就是单值二叉树。 只有给定的树是单值二叉树时&#xff0c;才返回 true&#xff1b;否则返回 false。 2. 解题 2.1 递归 class Solution { public:bool isUnivalT…

论文浅尝 - SIAM ICDM 2020 | 基于图时空网络的知识引导的诊断预测

论文笔记整理&#xff1a;吴锐&#xff0c;东南大学硕士。来源&#xff1a;SIAM ICDM 2020论文下载地址&#xff1a;https://epubs.siam.org/doi/abs/10.1137/1.9781611976236.3 动机基于电子病历&#xff08;EHR&#xff0c;Electronic Health Records&#xff09;对患者未来的…

Oceanus:美团HTTP流量定制化路由的实践

背景 Oceanus是美团基础架构部研发的统一HTTP服务治理框架&#xff0c;基于Nginx和ngx_lua扩展&#xff0c;主要提供服务注册与发现、动态负载均衡、可视化管理、定制化路由、安全反扒、session ID复用、熔断降级、一键截流和性能统计等功能。本文主要讲述Oceanus如何通过策略抽…

对商品的评论进行数据挖掘得到评论标签(商品属性+评论观点),以及用户的分组信息

对商品的评论进行数据挖掘得到评论标签&#xff08;商品属性评论观点&#xff09;&#xff0c;以及用户的分组信息&#xff1a; 第一步&#xff1a;对文本进行预处理&#xff0c;分词并进行语义角色标注 # -*- coding:utf-8 -*- import os from pyltp import Segmentor, Post…

文本对抗攻击入坑宝典

文 | 阿毅编 | 小轶如果是咱家公众号的忠实粉丝就一定还记得之前咱家一篇关于NLP Privacy的文章&#xff0c;不出意外的话&#xff0c;你们是不是现在依然还担心自己的隐私被输入法窃取而瑟瑟发抖。所以&#xff0c;我们又来了&#xff01;今天给大家讨论的是NLP Privacy中一个…

Android官方开发文档Training系列课程中文版:创建自定义View之View的交互

写在前面的话:这一章很有价值&#xff0c;想要提升安卓知识的一定要读一读。不做安卓的也可以得到其它方面的提升。 原文地址&#xff1a;http://android.xsoftlab.net/training/custom-views/making-interactive.html UI的绘制只是自定义View的一部分。你还需要使View可以以…

LeetCode 350. 两个数组的交集 II(哈希)

文章目录1. 题目2. 解题2.1 hash2.2 数组已排序1. 题目 给定两个数组&#xff0c;编写一个函数来计算它们的交集。 示例 1:输入: nums1 [1,2,2,1], nums2 [2,2] 输出: [2,2] 示例 2:输入: nums1 [4,9,5], nums2 [9,4,9,8,4] 输出: [4,9] 说明&#xff1a;输出结果中每个元…

会议交流 | CCKS2020 第十四届全国知识图谱与语义计算大会

CCKS2020第十四届全国知识图谱与语义计算大会China Conference on Knowledge Graph and Semantic Computing, 2020南昌.江西&#xff0c;11月12日-15日主办: 中国中文信息学会语言与知识计算专业委员会承办: 江西师范大学会议网站&#xff1a;www.sigkg.cn/ccks2020大会主题&a…

用微前端的方式搭建类单页应用

前言 微前端由ThoughtWorks 2016年提出&#xff0c;将后端微服务的理念应用于浏览器端&#xff0c;即将 Web 应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。 美团已经是一家拥有几万人规模的大型互联网公司&#xff0c;提升整体效率至关重要&#xff0c;这需要很…

Android官方开发文档Training系列课程中文版:创建自定义View之View的优化

原文地址&#xff1a;http://android.xsoftlab.net/training/custom-views/optimizing-view.html 现在已经完成了一个拥有良好设计的View&#xff0c;它即可以响应手势&#xff0c;又可以在状态之间过渡。为了避免View有卡顿的感觉&#xff0c;需要确保动画始终是按照每秒60帧…

12种NumpyPandas高效技巧

文 | Kunal Dhariwal本文分享给大家 12 种 Numpy 和 Pandas 函数&#xff0c;这些高效的函数会令数据分析更为容易、便捷。最后&#xff0c;读者也可以在 GitHub 项目中找到本文所用代码的 Jupyter Notebook。项目地址&#xff1a;https://github.com/kunaldhariwal/12-Amazing…

LeetCode 1002. 查找常用字符(哈希)

1. 题目 给定仅有小写字母组成的字符串数组 A&#xff0c;返回列表中的每个字符串中都显示的全部字符&#xff08;包括重复字符&#xff09;组成的列表。例如&#xff0c;如果一个字符在每个字符串中出现 3 次&#xff0c;但不是 4 次&#xff0c;则需要在最终答案中包含该字符…

抖音算法推荐机制详解

抖音算法推荐机制详解&#xff01;&#xff08;科普向&#xff09; 众所周知抖音的流量分配是去中心化的&#xff0c;这种去中心化算法&#xff0c;让每个人都有机会爆红&#xff0c;可为什么别人几个粉玩抖音&#xff0c;就能轻松获得10w点赞?而你怒拍几十条也枉然? 抖音的…

论文浅尝 - ICLR2020 | 用于半监督分类的图形推理学习

论文笔记整理&#xff1a;周虹廷&#xff0c;浙江大学研究生。研究方向&#xff1a;知识图谱&#xff0c;图表示学习等。论文链接&#xff1a;https://arxiv.org/pdf/2001.06137.pdf本文是发表在ICLR2020上针对图数据做节点半监督分类任务的论文。现有的算法解决图上节点分类问…

WMRouter:美团外卖Android开源路由框架

WMRouter是一款Android路由框架&#xff0c;基于组件化的设计思路&#xff0c;功能灵活&#xff0c;使用也比较简单。 WMRouter最初用于解决美团外卖C端App在业务演进过程中的实际问题&#xff0c;之后逐步推广到了美团其他App&#xff0c;因此我们决定将其开源&#xff0c;希望…

Android官方开发文档Training系列课程中文版:管理系统UI之变暗系统条

原文地址&#xff1a;http://android.xsoftlab.net/training/system-ui/index.html 引言 系统条(System Bars)是屏幕上的一块显示区域&#xff0c;专门用来显示通知&#xff0c;设备的通讯状态以及设备的导向。典型的System Bars与APP同时显示在屏幕上。APP展示了具体的内容&…

实话实说:中文自然语言处理的N个真实情况

文 | Liu Huanyong按语中文自然语言处理&#xff0c;目前在AI泡沫之下&#xff0c;真假难辨&#xff0c;实战技术与PPT技术往往存在着很大的差异。目前关于AI或者自然语言处理&#xff0c;做的人与讲的人往往是两回事。作者简介Liu Huanyong&#xff0c;就职于中国科学院软件研…

Android官方开发文档Training系列课程中文版:管理系统UI之隐藏状态条

原文地址&#xff1a;http://android.xsoftlab.net/training/system-ui/status.html 这节课将会介绍如何隐藏不同的版本的状态条。隐藏状态条可以使内容展示区域更大&#xff0c;因此可以提供一种更强的身临其境的用户体验。 含有状态条的APP&#xff1a; 隐藏状态条的APP&am…

python实现大批量pdf格式论文的重命名与目录制作功能

Python实现批量PDF文件统计处理&#xff1a;https://www.jianshu.com/p/1ec8f4314611 第一步&#xff1a;批量读取pdf文件 # -*- coding: utf-8 -*- """ Created on Sat Jun 8 15:30:22 2019 author: Administrator """import os from io impo…

论文浅尝 - ACL2020 | 用于回答知识库中的多跳复杂问题的查询图生成方法

论文笔记整理&#xff1a;谭亦鸣&#xff0c;东南大学博士。来源&#xff1a;ACL 2020链接&#xff1a;https://www.aclweb.org/anthology/2020.acl-main.91.pdf1.介绍在以往的工作中&#xff0c;知识图谱复杂问答一般被分为两种类型分别处理&#xff1a;其一是带有约束的问题&…