draw与dispatchDraw

2023-12-23 04:38
文章标签 draw dispatchdraw

本文主要是介绍draw与dispatchDraw,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

View类中的draw方法:

public void draw(Canvas canvas) {final int privateFlags = mPrivateFlags;final boolean dirtyOpaque = (privateFlags & PFLAG_DIRTY_MASK) == PFLAG_DIRTY_OPAQUE &&(mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);mPrivateFlags = (privateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;/** Draw traversal performs several drawing steps which must be executed* in the appropriate order:**      1. Draw the background:绘制背景*      2. If necessary, save the canvas' layers to prepare for fading*         :如有必要,颜色渐变淡之前保存画布层(即锁定原有的画布内容)*      3. Draw view's content:绘制view的内容*      4. Draw children:绘制子view*      5. If necessary, draw the fading edges and restore layers*         :如有必要,绘制颜色渐变淡的边框,并恢复画布(即画布改变的内容附加到原有内容上)*      6. Draw decorations (scrollbars for instance):绘制装饰,比如滚动条*/// Step 1, draw the background, if needed://背景绘制int saveCount;if (!dirtyOpaque) {drawBackground(canvas);}// skip step 2 & 5 if possible (common case)final int viewFlags = mViewFlags;boolean horizontalEdges = (viewFlags & FADING_EDGE_HORIZONTAL) != 0;boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0;if (!verticalEdges && !horizontalEdges) {// Step 3, draw the contentif (!dirtyOpaque) onDraw(canvas);// Step 4, draw the childrendispatchDraw(canvas);// Overlay is part of the content and draws beneath Foregroundif (mOverlay != null && !mOverlay.isEmpty()) {mOverlay.getOverlayView().dispatchDraw(canvas);}// Step 6, draw decorations (foreground, scrollbars)onDrawForeground(canvas);// we're done...return;}/** Here we do the full fledged routine...* (this is an uncommon case where speed matters less,* this is why we repeat some of the tests that have been* done above)*/boolean drawTop = false;boolean drawBottom = false;boolean drawLeft = false;boolean drawRight = false;float topFadeStrength = 0.0f;float bottomFadeStrength = 0.0f;float leftFadeStrength = 0.0f;float rightFadeStrength = 0.0f;// Step 2, save the canvas' layersint paddingLeft = mPaddingLeft;final boolean offsetRequired = isPaddingOffsetRequired();if (offsetRequired) {paddingLeft += getLeftPaddingOffset();}int left = mScrollX + paddingLeft;int right = left + mRight - mLeft - mPaddingRight - paddingLeft;int top = mScrollY + getFadeTop(offsetRequired);int bottom = top + getFadeHeight(offsetRequired);if (offsetRequired) {right += getRightPaddingOffset();bottom += getBottomPaddingOffset();}final ScrollabilityCache scrollabilityCache = mScrollCache;final float fadeHeight = scrollabilityCache.fadingEdgeLength;int length = (int) fadeHeight;// clip the fade length if top and bottom fades overlap// overlapping fades produce odd-looking artifactsif (verticalEdges && (top + length > bottom - length)) {length = (bottom - top) / 2;}// also clip horizontal fades if necessaryif (horizontalEdges && (left + length > right - length)) {length = (right - left) / 2;}if (verticalEdges) {topFadeStrength = Math.max(0.0f, Math.min(1.0f, getTopFadingEdgeStrength()));drawTop = topFadeStrength * fadeHeight > 1.0f;bottomFadeStrength = Math.max(0.0f, Math.min(1.0f, getBottomFadingEdgeStrength()));drawBottom = bottomFadeStrength * fadeHeight > 1.0f;}if (horizontalEdges) {leftFadeStrength = Math.max(0.0f, Math.min(1.0f, getLeftFadingEdgeStrength()));drawLeft = leftFadeStrength * fadeHeight > 1.0f;rightFadeStrength = Math.max(0.0f, Math.min(1.0f, getRightFadingEdgeStrength()));drawRight = rightFadeStrength * fadeHeight > 1.0f;}saveCount = canvas.getSaveCount();int solidColor = getSolidColor();if (solidColor == 0) {final int flags = Canvas.HAS_ALPHA_LAYER_SAVE_FLAG;if (drawTop) {canvas.saveLayer(left, top, right, top + length, null, flags);}if (drawBottom) {canvas.saveLayer(left, bottom - length, right, bottom, null, flags);}if (drawLeft) {canvas.saveLayer(left, top, left + length, bottom, null, flags);}if (drawRight) {canvas.saveLayer(right - length, top, right, bottom, null, flags);}} else {scrollabilityCache.setFadeColor(solidColor);}// Step 3, draw the content ://调用onDrawif (!dirtyOpaque) onDraw(canvas);// Step 4, draw the children ://绘制子viewdispatchDraw(canvas);// Step 5, draw the fade effect and restore layers : final Paint p = scrollabilityCache.paint;final Matrix matrix = scrollabilityCache.matrix;final Shader fade = scrollabilityCache.shader;if (drawTop) {matrix.setScale(1, fadeHeight * topFadeStrength);matrix.postTranslate(left, top);fade.setLocalMatrix(matrix);p.setShader(fade);canvas.drawRect(left, top, right, top + length, p);}if (drawBottom) {matrix.setScale(1, fadeHeight * bottomFadeStrength);matrix.postRotate(180);matrix.postTranslate(left, bottom);fade.setLocalMatrix(matrix);p.setShader(fade);canvas.drawRect(left, bottom - length, right, bottom, p);}if (drawLeft) {matrix.setScale(1, fadeHeight * leftFadeStrength);matrix.postRotate(-90);matrix.postTranslate(left, top);fade.setLocalMatrix(matrix);p.setShader(fade);canvas.drawRect(left, top, left + length, bottom, p);}if (drawRight) {matrix.setScale(1, fadeHeight * rightFadeStrength);matrix.postRotate(90);matrix.postTranslate(right, top);fade.setLocalMatrix(matrix);p.setShader(fade);canvas.drawRect(right - length, top, right, bottom, p);}canvas.restoreToCount(saveCount);// Overlay is part of the content and draws beneath Foregroundif (mOverlay != null && !mOverlay.isEmpty()) {mOverlay.getOverlayView().dispatchDraw(canvas);}// Step 6, draw decorations (foreground, scrollbars)onDrawForeground(canvas);
}

说明:

自定义一个view时,重写onDraw。调用view.invalidate(),会触发onDraw和computeScroll()。前提是该view被附加在当前窗口上.

Android中实现view的更新有两组方法,一组是invalidate,另一组是postInvalidate,其中前者是在UI线程自身中使用,而后者在非UI线程中使用。

自定义一个ViewGroup,重写onDraw。onDraw可能不会被调用,原因是需要先设置一个背景(颜色或图)。表示这个group有东西需要绘制了,才会触发draw,之后是onDraw。因此,一般直接重写dispatchDraw来绘制viewGroup

自定义一个ViewGroup,dispatchDraw会调用drawChild。

ViewGroup类dispatchDraw:

@Override
protected void dispatchDraw(Canvas canvas) {//......for (int i = 0; i < childrenCount; i++) {while (transientIndex >= 0 && mTransientIndices.get(transientIndex) == i) {final View transientChild = mTransientViews.get(transientIndex);if ((transientChild.mViewFlags & VISIBILITY_MASK) == VISIBLE ||transientChild.getAnimation() != null) {more |= drawChild(canvas, transientChild, drawingTime);}transientIndex++;if (transientIndex >= transientCount) {transientIndex = -1;}}final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex);if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {more |= drawChild(canvas, child, drawingTime);}}while (transientIndex >= 0) {// there may be additional transient views after the normal viewsfinal View transientChild = mTransientViews.get(transientIndex);if ((transientChild.mViewFlags & VISIBILITY_MASK) == VISIBLE ||transientChild.getAnimation() != null) {more |= drawChild(canvas, transientChild, drawingTime);}transientIndex++;if (transientIndex >= transientCount) {break;}}// Draw any disappearing views that have animationsif (mDisappearingChildren != null) {final ArrayList<View> disappearingChildren = mDisappearingChildren;final int disappearingCount = disappearingChildren.size() - 1;// Go backwards -- we may delete as animations finishfor (int i = disappearingCount; i >= 0; i--) {final View child = disappearingChildren.get(i);more |= drawChild(canvas, child, drawingTime);}}
}protected boolean drawChild(Canvas canvas, View child, long drawingTime) {return child.draw(canvas, this, drawingTime);
}

绘制VIew本身的内容,通过调用View.onDraw(canvas)函数实现,绘制自己的孩子通过dispatchDraw(canvas)实现

View组件的绘制会调用draw(Canvas canvas)方法,draw过程中主要是先画Drawable背景,对 drawable调用setBounds(),

然后是draw(Canvas c)方法.有点注意的是背景drawable的实际大小会影响view组件的大小,drawable的实际大小通过getIntrinsicWidth()和getIntrinsicHeight()获取,当背景比较大时view组件大小等于背景drawable的大小画完背景后,draw过程会调用onDraw(Canvas canvas)方法,

然后就是dispatchDraw(Canvas canvas)方法, dispatchDraw()主要是分发给子组件进行绘制,我们通常定制组件的时候重写的是onDraw()方法。

值得注意的是ViewGroup容器组件的绘制,当它没有背景时直接调用的是dispatchDraw()方法, 而绕过了draw()方法,当它有背景的时候就调用draw()方法,而draw()方法里包含了dispatchDraw()方法的调用。因此要在ViewGroup上绘制东西的时候往往重写的是dispatchDraw()方法而不是onDraw()方法,或者自定制一个Drawable,重写它的draw(Canvas c)和 getIntrinsicWidth(), getIntrinsicHeight()方法,然后设为背景。

这篇关于draw与dispatchDraw的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/526743

相关文章

Matlab draw a sector 画一个扇形

Matlab draw a sector 画一个扇形 Matlab的函数代码: function [ sector ] = Draw_a_sector( map, center,StartR, EndR, StartAngle, EndAngle )%% Get indexs(row,column)size_map=size(map);for i = 1:size_map(2)index

数据标注:批量转换json文件,出现AttributeError: module ‘labelme.utils‘ has no attribute ‘draw_label‘错误

labelme版本更换为3.11.2 "D:\Anaconda3\Lib\site-packages\labelme\utils\draw.py"缺失?: import ioimport os.path as ospimport numpy as npimport PIL.Imageimport PIL.ImageDrawimport PIL.ImageFontdef label_co

【教你一键解决】draw.io中输入英文显示成中文且输入位置移到首位

问题描述:当英文输入一个“a”时,会自动出现中文“一个”,再输入“a”才会出现“a”,删除时无法把中文删除,如下图所示。 解决方法:关闭浏览器的自动翻译功能即可,如下图所示。

x11 draw_pixels

对图像每个像素 统一 加一个值 创建一个图片 char *data = (char*)malloc(256*256*4);XImage *img = XCreateImage(display,visual,DefaultDepth(display,screen_num),ZPixmap,0,data,256,256,32,0); 调用 XAddPixel 添加值 int count =

C# 实现draw一个简单的温度计

运行结果 概述: 代码分析 该控件主要包含以下几个部分: 属性定义: MinValue:最低温度值。 MaxValue:最高温度值。 CurrentValue:当前温度值。 构造函数: 设置了一些控件样式来提升绘制效果,如 DoubleBuffer 以及 ResizeRedraw 等。 设定了控件的默认宽度和高度,并设置背景色和内边距。 绘制逻辑(在 OnPaint 方

Draw.io

Draw.io Draw.io是一款很实用的思维导图软件,现在已经推出了桌面版,对于很多办公人士而言画张流程图可以轻松的罗列整个流程,比使用文字或者幻灯片制作简单并且容易理解,该应用程序不仅免费,还拥有专业的工具,可让您创建图表和各种基于图像的流程图。您将无需再计划任何事情。它是迄今为止最容易使用的图表创建工具之一,具有友好的界面,丰富的功能和高度的自定义功能,所有这些功能均已集成到最终产品中。

arcgis for javascript- Draw画图结束添加多个图形问题

在Draw工具中 draw-end(画图结束后想地图添加图形) 发现第一次添加一个图形,第二次添加两个图形,第三次添加三个图形,依次递增 //新增图形function addLifeBoundary(){alert("新增图形");lifeFeatureLayer.clearSelection();lifeFeatureLayer.refresh();drawToolbar.activate

例54:Draw使用

建立一个控制台工程,输入代码: Screen 13 '移动到(50,50)而不绘图 Draw "BM 50,50"   'B:移动但不绘制,M:移动到指定位置 '将绘图颜色设置为2(绿色) Draw "C2"        'C将颜色改为n '画一个盒子 Draw "R50 D30 L50 U30"   'R表示右移动n个单位,D向下 ,L左,U上。 '在盒子里面移动 Draw

图标绘制软件draw.io中文安装包

Draw.io(也称为Diagrams)是一款功能强大的免费在线图表绘制工具。它支持绘制多种类型的图表,如流程图、UML图、组织结构图等,满足了从商务到工程设计的多领域需求。软件界面直观友好,操作简单,用户无需安装额外软件,即可直接在浏览器中使用。Draw.io还支持与云存储服务集成,方便用户保存和分享作品。此外,它还提供了丰富的导出选项,包括PDF、PNG等格式,满足不同用户的使用需求。 图标

draw.io 如何设置图形圆角?

draw.io 如何设置图形圆角呢? draw.io 是一款强大的,免费的开源工具,我经常用它来画流程图,但是我发现 draw.io 对于图形圆角的设置,只提供了一个设置选项,如下图: 当你选中某个图形,然后选中这里的“圆角”的时候,图像就会变成圆角,但是如果当你想把圆角再增大的时候,就没法设置了,工具面板上没有提供相关设置的选项。 这时候怎么办呢?例如我们要将一个矩形设置圆角的大小,可以