续前文“【Android】View绘制过程分析之layout",继续分析View的绘制过程。

本文分析第3阶段,分析过程的注释标记在以下代码中。

/** * 绘制过程 */public void draw(Canvas canvas) {    if (mClipBounds != null) {        canvas.clipRect(mClipBounds);    }    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;    /*     * 绘制过程依次进行下面的6步处理:     *      1. 绘制背景     *      2. If necessary, save the canvas' layers to prepare for fading     *      3. 绘制View的内容, 在onDraw(canvas)方法中完成     *      4. 绘制子View的内容     *      5. If necessary, draw the fading edges and restore layers     *      6. 绘制装饰品(如滚动条)     */    // 第1步,绘制背景    int saveCount;    if (!dirtyOpaque) {        final Drawable background = mBackground;        if (background != null) {            final int scrollX = mScrollX;            final int scrollY = mScrollY;            if (mBackgroundSizeChanged) {                background.setBounds(0, 0,  mRight - mLeft, mBottom - mTop);                mBackgroundSizeChanged = false;            }            if ((scrollX | scrollY) == 0) {                background.draw(canvas);            } else {                canvas.translate(scrollX, scrollY);                background.draw(canvas);                canvas.translate(-scrollX, -scrollY);            }        }    }    // 一般情况下,会跳过第2步与第5步    final int viewFlags = mViewFlags;    boolean horizontalEdges = (viewFlags & FADING_EDGE_HORIZONTAL) != 0;    boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0;    if (!verticalEdges && !horizontalEdges) {        // 第3步,绘制View的内容,自定义View时,这个方法需要我们去实现。        if (!dirtyOpaque) onDraw(canvas);        // 第4步,绘制子View的内容,参考ViewGroup中dispatchDraw(canvas)方法的实现,        //OK,你猜到了!又是一次遍历子View的过程,子View再调用draw(canvas)方法绘制自己及孙View。        //父View与子View这样的遍历过程,是Android一贯的做法。        dispatchDraw(canvas);        // 第6步,绘制装饰品(如滚动条)        onDrawScrollBars(canvas);        if (mOverlay != null && !mOverlay.isEmpty()) {            mOverlay.getOverlayView().dispatchDraw(canvas);        }        return;    }}/** * 绘制View的内容,在View类此方法空实现。但在自定义View类时,要实现此方法。 * 在这个方法中,可做的事情就多了,Canvas提供了丰富的绘图方法,关键是灵活运用! * 通常,你还可以通过调用以下方法或protected属性获取到一次绘制时需要用到的数值: * getMeasuredWidth()与getMeasuredHeight()  获取measure()中计算到的宽度与高度 *  mPaddingLeft, mPaddingTop, mPaddingRight, mPaddingBottom, mScrollX, mScrollY等等,直接使用。 */protected void onDraw(Canvas canvas) {}/** * 下面看一下ImageView的绘制: */protected void onDraw(Canvas canvas) {    super.onDraw(canvas);    if (mDrawable == null) {        return; // couldn't resolve the URI    }    if (mDrawableWidth == 0 || mDrawableHeight == 0) {        return;     // nothing to draw (empty bounds)    }    if (mDrawMatrix == null && mPaddingTop == 0 && mPaddingLeft == 0) {        mDrawable.draw(canvas);    } else {        int saveCount = canvas.getSaveCount();        canvas.save();                if (mCropToPadding) {            final int scrollX = mScrollX;            final int scrollY = mScrollY;            canvas.clipRect(scrollX + mPaddingLeft, scrollY + mPaddingTop,                    scrollX + mRight - mLeft - mPaddingRight,                    scrollY + mBottom - mTop - mPaddingBottom);        }                canvas.translate(mPaddingLeft, mPaddingTop);        if (mDrawMatrix != null) {            canvas.concat(mDrawMatrix);        }        mDrawable.draw(canvas);        canvas.restoreToCount(saveCount);    }}            

@容新华技术博客 - http://blog.csdn.net/rongxinhua - 原创文章,转载请注明出处


更多相关文章

  1. Android(安卓)VelocityTracker的使用
  2. Android(安卓)深入理解 View 的绘制流程和机制
  3. android 获取路径目录方法以及判断目录是否存在,创建目录
  4. Android(安卓)获取控件的宽和高
  5. android读取plist文件
  6. Android之Handler用法总结
  7. android获取安装的应用程序
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. mac使用Chrome模拟微信内置浏览器
  2. Android入门:搭建环境、工程目录剖析、Act
  3. android的触摸机制
  4. 如何让手机横竖屏切换不重走Activity生命
  5. android下res目录 资源定义及使用
  6. Android短信彩信收发流程(应用层)
  7. android事件处理总结--dispatchTouchEven
  8. Android中6.0及以上悬浮窗申请权限
  9. Appium -GitHub
  10. listview 设置数组为空