自定义View实现渲染

Posted JackWaiting

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义View实现渲染相关的知识,希望对你有一定的参考价值。

阅读前可以先看Android自定义图表:ChartView

需求:

通过以上例子我们修改测试数据后,拿到的View图像是这样的:

这里写图片描述

而我们要的效果是纵坐标7.45以上与5.97以下的部分为红色,7.45与6.43间为绿色,6.18与6.43之间为黄色,效果如下:

这里写图片描述

有了解自定义View的同学应该清楚从一个点画到另一个点的过程中,通过Paint与canvas.drawLine()绘制一条不同颜色的线是很不容易做到的,如果分成两条不同的线,无疑是更加增大了怎个绘制过程的复杂度。
那么我们如何去做成下图的这种效果。

1、初始化渲染背景的Rect

private Rect mColorBgRect = new Rect(0, mTopPadding, w, mColEndY);

2、渲染背景笔

    // 渲染背景笔
    public void shaderColorBgPaint(Rect rect) {
        LinearGradient linearGradient = new LinearGradient(rect.left, rect.top, rect.left, rect.bottom, getShaderColor(), getShaderPosition(), Shader.TileMode.MIRROR);
        mColorBgPaint.setShader(linearGradient);
    }

    // 将正常理解的颜色@COLORS_SHADER转换为LinearGradient绘制所需的颜色
    public int[] getShaderColor(){
        int[] colors = new int[COLORS_SHADER.length * 2];
        for (int i = 0, len = colors.length; i < len ; i+=2) {
            colors[i] = COLORS_SHADER[i/2];
            colors[i+1] = COLORS_SHADER[i/2];
        }
        return colors;
    }

    // 将正常理解的比例@RATios_SHADER转换为LinearGradient绘制所需的比例
    public float[] getShaderPosition() {
        float[] position = new float[COLORS_SHADER.length * 2];
        position[0] = JOIN_SHADER;
        position[1] = RATIOS_SHADER[0] - JOIN_SHADER;
        for (int i = 1, len = RATIOS_SHADER.length; i < len ; i++) {
            position[i*2] = RATIOS_SHADER[i-1] + JOIN_SHADER;
            position[i*2+1] = RATIOS_SHADER[i] - JOIN_SHADER;
        }
        return position;
    }

3、设置setShader()所需要的Shader

mColorBgPaint.setShader(linearGradient);  

4、绘制一个渲染的背景

      // 绘制一个渲染的背景
        Bitmap tagBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        Canvas tagCanvas = new Canvas(tagBitmap);
        tagCanvas.drawRect(mColorBgRect, mColorBgPaint);

5、绘制显示的数据–这里是曲线

        // 绘制曲线
        Bitmap curveBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
        Canvas curveCanvas = new Canvas(curveBitmap);
        drawCurve(curveCanvas);  //这个方法是具体的绘制,后面会给出源码地址

6、设置合成模式PorterDuff.Mode.DST_IN

        Paint paint = new Paint(); 
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); // 设置合成模式
        tagCanvas.drawBitmap(curveBitmap, mMatrix, paint);

其中具体的PorterDuff.Mode.DST_IN为 取两层绘制交集。显示下层这里就是取下层的背景色。
具体关于setXfermode的了解,可以看以下链接
android PorterDuffXfermode ,PorterDuff.Mode 使用 以及Porter-Duff规则详解

7、绘制渲染后的曲线图

    // 绘制渲染后的曲线图
    private void drawBeautifulCurve(Canvas canvas) {
        if (mCurveBitmap == null) {
            mCurveBitmap = getBeautfulCurve();
        }
        canvas.drawBitmap(mCurveBitmap, 0, 0, null);
    }

通过以上步骤即可完成对图形的渲染绘制,具体的代码已更新至Github中,

本期优化内容:

1、添加点击、滑动事件,通过点击与滑动即可查看当前点的具体信息。
2、优化屏幕适配。
3、点击外区域取消当前信息显示。
4、渲染当前先的绘制颜色。

以下是最新下载链接:

Github下载地址:https://github.com/JackWaiting/ChartView

以上是关于自定义View实现渲染的主要内容,如果未能解决你的问题,请参考以下文章

Android 自定义可拖拽View,界面渲染刷新后不会自动回到起始位置

Android:在片段内膨胀自定义视图

VS Code中自定义Emmet代码片段

Visual Studio 自定义代码片段在方法定义的参数列表中不起作用

VS中添加自定义代码片段——偷懒小技巧

如何在片段 xml 中使用自定义组件?