自定义视图中最重要的部分是它的外观。根据您的应用需求,自定义绘图可以很容易或复杂。
本课包含一些最常见的操作

覆盖onDraw()

绘制自定义视图中最重要的步骤是重写该onDraw()方法。参数to onDraw()是Canvas视图可以用来绘制自己的对象。在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));...

提前创建对象是一项重要的优化。视图经常重绘,许多图形对象需要昂贵的初始化。在您的onDraw() 方法中创建绘图对象会显着降低性能,并可能导致UI显得呆滞

处理布局事件

为了正确绘制自定义视图,您需要知道它的大小。复杂的自定义视图通常需要执行多个布局计算,具体取决于屏幕上区域的大小和形状。你绝对不应该对屏幕上的视图大小做出假设。即使只有一个应用使用您的视图,该应用也需要在纵向和横向模式下处理不同的屏幕尺寸,多种屏幕密度以及各种纵横比。

虽然View有许多处理度量的方法,但大多数方法都不需要被覆盖。如果你的视图不需要特殊控制它的大小,你只需要重写一个方法:onSizeChanged()。

onSizeChanged()在您的视图首次分配大小时调用,并且如果视图的大小因任何原因而发生更改,则会再次调用该视图。计算与您的视图尺寸相关的位置,尺寸和任何其他值 onSizeChanged(),而不是每次绘制时重新计算它们。在该PieChart例子中,onSizeChanged()是在PieChart图计算饼图的外接矩形和文本标签和其他视觉元素的相对位置。

当您的视图分配了大小时,布局管理器会假定大小包含所有视图的填充。计算视图大小时,您必须处理填充值。这里有一个片段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);

如果您需要更好地控制视图的布局参数,请执行onMeasure()。这个方法的参数是 View.MeasureSpec告诉你视图的父视图有多大的值,以及这个大小是一个硬性最大值还是一个建议值。作为优化,这些值被存储为打包整数,并使用静态方法 View.MeasureSpec来解压存储在每个整数中的信息。

这是一个示例实现onMeasure()。在这个实现中,PieChart 试图使它的面积足够大,以使饼与其标签一样大:

@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);
}

在这个代码中有三件重要的事情需要注意:

计算考虑了视图的填充。如前所述,这是观点的责任。
辅助方法resolveSizeAndState()用于创建最终的宽度和高度值。该帮助程序View.MeasureSpec通过将视图的所需大小与传入的规范进行比较来返回适当的 值 onMeasure()。
onMeasure()没有回报价值。相反,该方法通过调用来传递其结果setMeasuredDimension()。调用此方法是强制性的。如果您省略此调用,则View该类会引发运行时异常

一旦你定义了对象创建和测量代码,你就可以实现onDraw()。每个视图的实现onDraw() 方式都不相同,但大多数视图共享一些常见操作:

Draw!

使用绘制文本drawText()。通过调用指定字体setTypeface(),并通过调用指定文字颜色setColor()。
通过绘制基本形状drawRect(),drawOval()和drawArc()。通过调用来更改形状是否填充,勾勒或两者兼而有之setStyle()。
使用Path该类绘制更复杂的形状。通过向Path对象添加直线和曲线来定义形状 ,然后使用绘制形状drawPath()。就像原始形状一样,根据路径可以勾勒出轮廓,填充或两者 setStyle()。
通过创建LinearGradient对象来定义渐变填充。呼吁setShader()使用你 LinearGradient的填充形状。
使用绘制位图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);
}

参考文章
https://developer.android.google.cn/training/custom-views/custom-drawing.html#layouteevent

Android自定义控件学习(五)-------自定义绘图相关推荐

  1. android webrtc学习五(webrtc视频数据传递和切换摄像头问题处理)

    android webrtc学习五(webrtc视频数据传递和切换摄像头问题处理) Android webrtc摄像头流程分析 1.打开摄像头 2.获取流数据 摄像头切换 问题场景:在使用华为手机(忘 ...

  2. Android自定义控件学习(三)----- 自定义视图组件

    自定义视图组件 说明 Android提供了用于构建UI的基础上,基本布局类一个复杂和强大的组件化模式:View和 ViewGroup.首先,该平台包含各种预构建的View和ViewGroup子类 - ...

  3. Android自定义控件学习(一)-----属性

    Android中XML的命名空间.自定义属性 命名空间(namespace) XML 命名空间提供避免元素命名冲突的方法. 打个比方,A学校有名学生叫做林小明,B学校也有名学生叫林小明,那我们如何识别 ...

  4. Android JNI学习(五)——Java与Native之间如何实现相互调用

    本章将讲述Java与Native之间如何实现相互调用.我将围绕围绕如下三点来讲解. #mermaid-svg-qeVnGlVrLWrB5ryX .label{font-family:'trebuche ...

  5. Android自定义控件面试题,自定义View面试总结

    本着针对面试,不负责任的态度,写下<面试总结>系列.本系列记录面试过程中各个知识点,而不是入门系列,如果有不懂的自行学习. 自定义View三种方式,组合现有控件,继承现有控件,继承View ...

  6. Android自定义控件学习(四)------创建一个视图类

    创建一个视图类 精心设计的自定义视图与其他精心设计的类非常相似.它使用易于使用的界面封装了一组特定的功能,它可以高效地使用CPU和内存,等等.不过,作为一个设计良好的设计,自定义视图应该: 符合And ...

  7. Android自定义控件学习(二)-----自定义attr Style styleable以及其应用

    相信每一位从事Android开发的猿都遇到过需要自己去自定义View的需求,如果想通过xml指定一些我们自己需要的参数,就需要自己声明一个styleable,并在里面自己定义一些attr属性,这个过程 ...

  8. Android 自定义控件起步:自定义TextView

    转载至:http://blog.csdn.net/lmj623565791/article/details/24252901 不过对原作进行了相关细节优化,所以才有此文.. 首先我们看一下我们要达到的 ...

  9. Android 自定义控件-Canvas和Paint绘图详解-手把手带你绘制一个时钟.

    Android - Paint基础 在自定义控件时,经常需要使用canvas.paint等,在canvas类中,绘画基本都是靠drawXXX()方法来完成的,在这些方法中,很多时候都需要用到paint ...

最新文章

  1. JFlash ARM对stm32程序的读取和烧录
  2. 看完这篇,Oracle数据库运维不用愁
  3. 使用WampServer搭建本地PHP环境,绑定域名,配置伪静态
  4. QML-关于Qt.rgba()颜色无法正常显示问题
  5. 【转载】(Git)用动图展示10大Git命令
  6. (14)FPGA面试题线与逻辑
  7. reduceByKey与GroupByKey,为什么尽量少用GroupByKey
  8. IntelliJ IDEA License Activation系列验证爆错: This license BIG3CLIK6F has been cancelled d 解决
  9. mysql5.6 table cache_MySQL 5.6下table_open_cache参数优化合理配置详解
  10. java实现一个简单的打字游戏
  11. oracle执行计划更新,请教update和delete的执行计划
  12. 妨碍编译器优化的因素
  13. 计算机专业英语问卷调查,关于英语调查问卷的总结
  14. Windows Defender保护历史记录清空方法
  15. typora免费将图片上传到CSDN
  16. 定制网站建设流程有哪些
  17. 【模电】0014 运放自激振荡和消除(补偿)
  18. Android APT不能自动生成文件
  19. 阿里达摩院数学竞赛新一轮考题曝光,李永乐老师曾给出第一题详细解答
  20. 中文自动文本摘要生成指标计算,Rouge/Bleu/BertScore/QA代码实现

热门文章

  1. java堆算法_用Java写算法之七:堆排序
  2. java excel自动保存_比POI好用的EasyExcel简单使用记录
  3. OpenShift 4 - 为Gogs构建一个Operator
  4. Visual Studio 远程调试正在运行的进程
  5. MQTT——具有.NET Core的消息队列遥测传输协议
  6. Android 10 正式版本或将于 9 月 3 日推出
  7. 递增三元组蓝桥杯c语言,蓝桥-递增三元组-蓝桥
  8. python新闻联播分类_如何利用人脸识别自动切分视频
  9. ajaxsetup获取ajax的url_跨域调用接口的方法之一:$.ajaxSetup()
  10. oracle取第一位,Oracle中的substr()函数和INSTR()函数