美文网首页
自定义控件其实很简单(笔记二)

自定义控件其实很简单(笔记二)

作者: 北疆_ | 来源:发表于2016-04-15 10:27 被阅读61次

    原博客地址: 自定义控件其实很简单1/3

    Matrix


    乘法
    Scale Scale
    旋转

    根据三角函数的关系我们可以得出p(x,y)的坐标:

    同样根据三角函数的关系我们也可以得出p(x0,y0)的坐标:

    上述两公式结合我们则可以得出简化后的p(x,y)的坐标:

    这是什么公式呢?是不是就是上面矩阵的乘积呢?囧……
    绕点p(a,b)顺时针转:
    其实绕某个点旋转没有想象中的那么复杂,相对于绕中心点来说就多了两步:先将坐标原点移到我们的p(a,b)处然后执行旋转最后再把坐标圆点移回去:

    实践
    matrix.preScale(0.5f, 1); 
    matrix.setScale(1, 0.6f); 
    matrix.postScale(0.7f, 1); 
    matrix.preTranslate(15, 0);
    
    • Matrix的计算过程:translate (15, 0) -> scale (1, 0.6f) -> scale (0.7f, 1)
    matrix.preScale(0.5f, 1); 
    matrix.preTranslate(10, 0);
    matrix.postScale(0.7f, 1);  
    matrix.postTranslate(15, 0);
    
    • 计算过程: translate (10, 0) -> scale (0.5f, 1) -> scale (0.7f, 1) -> translate (15, 0)

    Canvas Advance

    原文章:[1] 自定义控件其实很简单5/12
    [drawBitmapMesh](http://developer.android.com/reference/android/graphics/Canvas.html#drawBitmapMesh(android.graphics.Bitmap, int, int, float[], int, int[], int, android.graphics.Paint))(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, Paint paint)

    Sample-1

    float multiple = mBitmap.getWidth();
            for (int y = 0; y <= 19; y++) { //1. 把位图分为19顶点值
                float fy = mBitmap.getHeight() * y / 19;
                for (int x = 0; x <= W; x++) {
                                    // fx方向的顶点值+偏移
                    float fx = mBitmap.getWidth() * x / 19 + ((19 - y) * 1.0F / 19 * multiple);
                    setXY(fx, fy, index);
                    index += 1;
                }
            }
    canvas.drawBitmapMesh(mBitmap, 19, 19, verts, 0, null, 0, null);
    

    Sample-2

    int index = 0;
    float multipleY = mBitmap.getHeight() / HEIGHT;
    float multipleX = mBitmap.getWidth() / WIDTH;
    for (int y = 0; y <= HEIGHT; y++) {
        float fy = multipleY * y;
        for (int x = 0; x <= WIDTH; x++) {
            float fx = multipleX * x;
            setXY(fx, fy, index);
            if (5 == y) {
                if (8 == x) {
                    setXY(fx - multipleX, fy - multipleY, index);
                }
                if (9 == x) {
                    setXY(fx + multipleX, fy - multipleY, index);
                }
            }
            if (6 == y) {
                if (8 == x) {
                    setXY(fx - multipleX, fy + multipleY, index);
                }
                if (9 == x) {
                    setXY(fx + multipleX, fy + multipleY, index);
                }
            }
            index += 1;
        }
    }
    
    • Canvas对象概略:

    在framework中,Activty被创建时(更准确地说是在addView的时候)会同时创建一个叫做ViewRootImpl的对象,ViewRootImpl是个很碉堡的类,它负责很多GUI的东西,包括我们常见的窗口显示、用户的输入输出等等,同时,它也负责Window跟WMS通信(Window你可以想象是一个容器,里面包含着我们的一个Activity,而AMS呢全称为Activity Manager Service,顾名思义很好理解它的作用),当ViewRootImpl跟WMS建立通信注册了Window后就会发出第一次渲染View Hierachy的请求,涉及到的方法均在ViewRootImpl下:setView、requestLayout、scheduleTraversals等,大家有兴趣可以自己去搜罗看看,在performTraversals方法中ViewRootImpl就会去创建Surface,而此后的渲染则可以通过Surface的lockCanvas方法获取Surface的Canvas来进行,然后遍历View Hierachy把需要绘制的View通过Canvas(View.onDraw(Canvas canvas))绘制到Surface上,绘制完成后解锁(Surface.unlockCanvasAndPost)让SurfaceFlinger将Surface绘制到屏幕上。

    • Canvas分类:
    • 第一是以drawXXX为主的绘制方法,
    • 第二是以clipXXX为主的裁剪方法,
    • 第三是以scale、skew、translate和rotate组成的Canvas变换方法,
    • 最后一类则是以saveXXX和restoreXXX构成的画布锁定和还原

    Rect

    • intersect
    mRect = new Rect(0, 0, 500, 500);
    mRect.intersect(250, 250, 750, 750);
    canvas.clipRect(mRect);
    
    • union
    mRect.union(250, 250, 750, 750);

    相关文章

      网友评论

          本文标题: 自定义控件其实很简单(笔记二)

          本文链接:https://www.haomeiwen.com/subject/yktghttx.html