【原始密源码】【eletron源码】【mtklogger 源码】draw 源码

来源:ballz 源码

1.arcgis 源码api 3.x for js 入门开发系列五地态势标绘(附源码)
2.技术系列开源之DrawDocker源码略读(一)
3.Android UI绘制之View绘制的工作原理

draw 源码

arcgis api 3.x for js 入门开发系列五地态势标绘(附源码)

       关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的源码 arcgis api 3.x for js: esri 官网 api,里面详细的源码介绍 arcgis api 3.x 各个类的介绍,还有就是源码在线例子: esri 官网在线例子,这个也是源码学习 arcgis api 3.x 的好素材。

       内容概览

       基于arcgis 源码原始密源码api 的 Draw 工具基本绘制 拓展 Draw 工具的绘制 源代码 demo 下载

       本篇实现地图态势标绘功能模块

       截图如下

       本篇核心的在于调用 arcgis api 的 Draw 工具: Draw

       构造函数:

       一般来说,传参 map 对象进来就行,源码其他参数可选的源码,用默认的源码就行,除非你想专门设置。源码 默认的源码可绘制图形类型常量 Constants:

       可以设置绘制的符号样式:

       其中,activate 函数可以激活触发绘制的源码行为,绘制结束之后在绘制结束事件里面获取 geometry:

       地图态势标绘实现的源码思路:利用 arcgis api 的 Draw工具实现普通的点线面绘制,但是源码对于燕尾箭头、集结地、源码弧线、曲线、简单箭头等特殊的军事态势需要自定义来绘制了,所以需要拓展 Draw 工具才能实现,eletron源码也是本篇的精华所在。

       1是继承拓展 Draw 的文件目录;2是实现态势标绘模块的 js 文件。 首先,需要在 map.html 页面引用进来:

       其中,paths 代表需要引用的路径。

       其次,在 map.js 文件的初始化里面引用拓展的 js 文件 DrawEx 以及 DrawExt:

       最后,在工具栏菜单的态势标绘菜单响应事件里面调用 plot.js 即可:

       其次,触发调用 Draw 绘制:

       最后,mtklogger 源码添加绘制图形在地图上展示:

       demo源码下载 下载提取码:g5cy

技术系列开源之DrawDocker源码略读(一)

       本文由神州数码云基地团队整理撰写,若需转载,请注明出处。本文将简要解析开源图形化工具“神笔马良”(DrawDocker)的设计引擎和设计试图视角功能,以供后续开发者参考。分析基于年月日的master分支代码,读者应依据实际情况进行判断。

       项目包含侧栏、画布和右侧格式栏,asiagaming 源码以及上方工具栏。侧栏提供搜索图形、便笺本、自定义Kubeapps组件栏、更多图形按钮等功能。其中,搜索图形功能通过关键字实现,由Sidebar对象的addSearchPalette方法控制。便笺本功能则用于保存临时图形模板,源码吾爱自定义Kubeapps组件栏则能展示并生成自定义应用组件。Kubeapps应用组件栏显示所有应用组件模板,通过读取kubeappsPalette.json文件的数据,创建包含图形、应用名、chart名和chart地址等信息的应用组件。

       创建新的组件栏需新增添加面板方法,并在初始化时调用。更多图形方法位于MoreShapesDialog中,新建的组件栏需添加至条目中才能在“更多图形”中显示。自定义属性或格式图形模板需在shapes和stencils目录下创建相应文件。

       画布部分主要由mxGraph对象实现,提供选中、获得样式等功能。右侧格式栏提供绘图、样式、文本、调整图形和安装参数栏,依据选中状态动态显示。样式栏显示图形属性及其值,若为Kubeapps图形,显示应用名、安装状态等。安装参数栏显示安装或删除按钮等。工具栏包含菜单、撤销、重做、删除、重命名、保存、语言等功能,通过Actions、EditorUi等对象实现。

       如需改进安装功能,可在Actions对象中修改或定义新动作,甚至在AppController.java文件中调整。项目已开源在GitHub,有兴趣的开发者可自行探索和优化。

Android UI绘制之View绘制的工作原理

        这是AndroidUI绘制流程分析的第二篇文章,主要分析界面中View是如何绘制到界面上的具体过程。

        ViewRoot 对应于 ViewRootImpl 类,它是连接 WindowManager 和 DecorView 的纽带,View的三大流程均是通过 ViewRoot 来完成的。在 ActivityThread 中,当 Activity 对象被创建完毕后,会将 DecorView 添加到 Window 中,同时会创建 ViewRootImpl 对象,并将 ViewRootImpl 对象和 DecorView 建立关联。

        measure 过程决定了 View 的宽/高, Measure 完成以后,可以通过 getMeasuredWidth 和 getMeasuredHeight 方法来获取 View 测量后的宽/高,在几乎所有的情况下,它等同于View的最终的宽/高,但是特殊情况除外。 Layout 过程决定了 View 的四个顶点的坐标和实际的宽/高,完成以后,可以通过 getTop、getBottom、getLeft 和 getRight 来拿到View的四个顶点的位置,可以通过 getWidth 和 getHeight 方法拿到View的最终宽/高。 Draw 过程决定了 View 的显示,只有 draw 方法完成后 View 的内容才能呈现在屏幕上。

        DecorView 作为顶级 View ,一般情况下,它内部会包含一个竖直方向的 LinearLayout ,在这个 LinearLayout 里面有上下两个部分,上面是标题栏,下面是内容栏。在Activity中,我们通过 setContentView 所设置的布局文件其实就是被加到内容栏中的,而内容栏id为 content 。可以通过下面方法得到 content:ViewGroup content = findViewById(R.android.id.content) 。通过 content.getChildAt(0) 可以得到设置的 view 。 DecorView 其实是一个 FrameLayout , View 层的事件都先经过 DecorView ,然后才传递给我们的 View 。

        MeasureSpec 代表一个位的int值,高2位代表 SpecMode ,低位代表 SpecSize , SpecMode 是指测量模式,而 SpecSize 是指在某种测量模式下的规格大小。

        SpecMode 有三类,如下所示:

        UNSPECIFIED

        EXACTLY

        AT_MOST

        LayoutParams需要和父容器一起才能决定View的MeasureSpec,从而进一步决定View的宽/高。

        对于顶级View,即DecorView和普通View来说,MeasureSpec的转换过程略有不同。对于DecorView,其MeasureSpec由窗口的尺寸和其自身的LayoutParams共同确定;

        对于普通View,其MeasureSpec由父容器的MeasureSpec和自身的Layoutparams共同决定;

        MeasureSpec一旦确定,onMeasure就可以确定View的测量宽/高。

        小结一下

        当子 View 的宽高采用 wrap_content 时,不管父容器的模式是精确模式还是最大模式,子 View 的模式总是最大模式+父容器的剩余空间。

        View 的工作流程主要是指 measure 、 layout 、 draw 三大流程,即测量、布局、绘制。其中 measure 确定 View 的测量宽/高, layout 确定 view 的最终宽/高和四个顶点的位置,而 draw 则将 View 绘制在屏幕上。

        measure 过程要分情况,如果只是一个原始的 view ,则通过 measure 方法就完成了其测量过程,如果是一个 ViewGroup ,除了完成自己的测量过程外,还会遍历调用所有子元素的 measure 方法,各个子元素再递归去执行这个流程。

        如果是一个原始的 View,那么通过 measure 方法就完成了测量过程,在 measure 方法中会去调用 View 的 onMeasure 方法,View 类里面定义了 onMeasure 方法的默认实现:

        先看一下 getSuggestedMinimumWidth 和 getSuggestedMinimumHeight 方法的源码:

        可以看到, getMinimumWidth 方法获取的是 Drawable 的原始宽度。如果存在原始宽度(即满足 intrinsicWidth > 0),那么直接返回原始宽度即可;如果不存在原始宽度(即不满足 intrinsicWidth > 0),那么就返回 0。

        接着看最重要的 getDefaultSize 方法:

        如果 specMode 为 MeasureSpec.UNSPECIFIED 即未指定模式,那么返回由方法参数传递过来的尺寸作为 View 的测量宽度和高度;

        如果 specMode 不是 MeasureSpec.UNSPECIFIED 即是最大模式或者精确模式,那么返回从 measureSpec 中取出的 specSize 作为 View 测量后的宽度和高度。

        看一下刚才的表格:

        当 specMode 为 EXACTLY 或者 AT_MOST 时,View 的布局参数为 wrap_content 或者 match_parent 时,给 View 的 specSize 都是 parentSize 。这会比建议的最小宽高要大。这是不符合我们的预期的。因为我们给 View 设置 wrap_content 是希望View的大小刚好可以包裹它的内容。

        因此:

        如果是一个 ViewGroup,除了完成自己的 measure 过程以外,还会遍历去调用所有子元素的 measure 方法,各个子元素再递归去执行 measure 过程。

        ViewGroup 并没有重写 View 的 onMeasure 方法,但是它提供了 measureChildren、measureChild、measureChildWithMargins 这几个方法专门用于测量子元素。

        如果是 View 的话,那么在它的 layout 方法中就确定了自身的位置(具体来说是通过 setFrame 方法来设定 View 的四个顶点的位置,即初始化 mLeft , mRight , mTop , mBottom 这四个值), layout 过程就结束了。

        如果是 ViewGroup 的话,那么在它的 layout 方法中只是确定了 ViewGroup 自身的位置,要确定子元素的位置,就需要重写 onLayout 方法;在 onLayout 方法中,会调用子元素的 layout 方法,子元素在它的 layout 方法中确定自己的位置,这样一层一层地传递下去完成整个 View 树的 layout 过程。

        layout 方法的作用是确定 View 本身的位置,即设定 View 的四个顶点的位置,这样就确定了 View 在父容器中的位置;

        onLayout 方法的作用是父容器确定子元素的位置,这个方法在 View 中是空实现,因为 View 没有子元素了,在 ViewGroup 中则进行抽象化,它的子类必须实现这个方法。

        1.绘制背景( background.draw(canvas); );

        2.绘制自己( onDraw );

        3.绘制 children( dispatchDraw(canvas) );

        4.绘制装饰( onDrawScrollBars )。

        dispatchDraw 方法的调用是在 onDraw 方法之后,也就是说,总是先绘制自己再绘制子 View 。

        对于 View 类来说, dispatchDraw 方法是空实现的,对于 ViewGroup 类来说, dispatchDraw 方法是有具体实现的。

        通过 dispatchDraw 来传递的。 dispatchDraw 会遍历调用子元素的 draw 方法,如此 draw 事件就一层一层传递了下去。dispatchDraw 在 View 类中是空实现的,在 ViewGroup 类中是真正实现的。

        如果一个 View 不需要绘制任何内容,那么就设置这个标记为 true,系统会进行进一步的优化。

        当创建的自定义控件继承于 ViewGroup 并且不具备绘制功能时,就可以开启这个标记,便于系统进行后续的优化;当明确知道一个 ViewGroup 需要通过 onDraw 绘制内容时,需要关闭这个标记。

        参考:《Android开发艺术探索》

文章所属分类:时尚频道,点击进入>>