Android PathEffect 自定义折线图必备

Posted 单灿灿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android PathEffect 自定义折线图必备相关的知识,希望对你有一定的参考价值。

要想实现这样的折线图表难吗?看完这一篇之后,自定义折线图全是小事。


android Paint的使用使我们自定义View不可或缺的东西,其中有一个方法setPathEffect(PathEffect effect)没有详细介绍,这篇就结合代码来介绍一下,在之前说过PathEffect共有6个子类ComposePathEffect,CornerPathEffect,DashPathEffect,DiscretePathEffect,PathDashPathEffect,SumPathEffect,PathEffect这个路径效果类没有具体的实现,效果是由它的六个子类实现的。

一、PathEffect()

这六个子类分别可以实现不同的路径效果:

上了效果图,我们来上一个代码:

二、代码

/**
 * Created by Shanlovana on 2017-03-26.
 */

public class PathView extends View 
    // 实例化画笔
    private Paint mPaint = null;
    private Path mPath;// 路径对象
    private Context mContext;


    public PathView(Context context) 
        this(context, null);
    

    public PathView(Context context, AttributeSet attrs) 
        this(context, attrs, 0);
    

    public PathView(Context context, AttributeSet attrs, int defStyleAttr) 
        super(context, attrs, defStyleAttr);
        // 初始化画笔
        initPaint();
        //初始化path
        initPath();


    

    private void initPath() 
        // 实例化路径
        mPath = new Path();
        // 定义路径的起点
        mPath.moveTo(10, 50);

        // 定义路径的各个点
        for (int i = 0; i <= 20; i++) 
            mPath.lineTo(i * 20, (float) (Math.random() * 100));
        
    


    private void initPaint() 
        // 实例化画笔并打开抗锯齿
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(5);
        mPaint.setColor(Color.DKGRAY);
    

    /*
   * 绘制view时调用的方法,可能会出现多次调用,所以不建议在这里面实例化对象,也就是不要出现new
   *
   * @param canvas 一个画布对象,我们可以用paint在上面画画
   */
    @Override
    protected void onDraw(Canvas canvas) 
        super.onDraw(canvas);
        int phase = 1;

        /*
         * 绘制路径
         */
        // 没有做处理,还没有写代码
        mPaint.setPathEffect(null);//什么都不设置,没有做处理,显示生硬
        canvas.drawPath(mPath, mPaint);

        canvas.translate(0, 100);//下移100dp
        /*
         * 绘制路径
         */
        //
        mPaint.setPathEffect(new CornerPathEffect(10));
        canvas.drawPath(mPath, mPaint);
        canvas.translate(0, 100);//下移100dp
        /*
         * 绘制路径
         */
        //
        mPaint.setPathEffect(new DiscretePathEffect(3.0F, 5.0F));
        canvas.drawPath(mPath, mPaint);
        canvas.translate(0, 100);//下移100dp
        /*
         * 绘制路径
         */
        //
        mPaint.setPathEffect(new DiscretePathEffect(10.0F, 2.0F));
        canvas.drawPath(mPath, mPaint);
        canvas.translate(0, 100);//下移100dp
        /*
         * 绘制路径
         */
        //
        mPaint.setPathEffect(new DashPathEffect(new float[]20, 10, 1));
        canvas.drawPath(mPath, mPaint);

        //这个绘制需拉出去单独写,才会有动态效果,此处就是为了统一展示  ---start
        canvas.translate(0, 100);//下移100dp
        /*
         * 绘制路径
         */
        //
        mPaint.setPathEffect(new DashPathEffect(new float[]20, 10, 50, 5, 100, 30, 10, 5, phase));
        canvas.drawPath(mPath, mPaint);
        phase++;
        invalidate();
        //这个绘制需拉出去单独写,才会有动态效果,此处就是为了统一展示  ---end


        //2,这个绘制需拉出去单独写,才会有动态效果,此处就是为了统一展示  ---start
        canvas.translate(0, 100);//下移100dp
        /*
         * 绘制路径
         */
        //
        Path path = new Path();
        path.addCircle(0, 0, 3, Path.Direction.CCW);
        PathEffect pathEffect = new PathDashPathEffect(path, 12, phase, PathDashPathEffect.Style.ROTATE);

        mPaint.setPathEffect(pathEffect);
        canvas.drawPath(mPath, mPaint);
        // 改变偏移值
        phase++;
        // 重绘,产生动画效果
        invalidate();
        //2,这个绘制需拉出去单独写,才会有动态效果,此处就是为了统一展示  ---end


    

三、代码讲解

下面对照着代码,我们来讲解一下:

在使用的时候,通常是

PathEffect pe = new 一个具体的子类;

然后使用Paint的setPathEffect(PathEffect pe)方法即可。

1,不设置效果

 mPaint.setPathEffect(null);

2,设置CornerPathEffect

这个类的作用就是将Path的各个连接线段之间的夹角用一种更平滑的方式连接,类似于圆弧与切线的效果。
一般的,通过CornerPathEffect(float radius)指定一个具体的圆弧半径来实例化一个CornerPathEffect。

3,设置DiscretePathEffect

DiscretePathEffect(离散路径效果)相对来说则稍微复杂点,其会在路径上绘制很多“杂点”的突出来模拟一种类似生锈铁丝的效果。其构造方法有两个参数:

  • 第一个呢指定这些突出的“杂点”的密度,值越小杂点越密集;
  • 第二个参数呢则是“杂点”突出的大小,值越大突出的距离越大反之反之。

当我们设置杂点密度很大,突出距离较小时,你会发现线条也变得柔和了起来。

线条三与四的比较

4,DashPathEffect:

这个类的作用就是将Path的线段虚线化。
构造函数为DashPathEffect(float[] intervals, float offset),其中intervals为虚线的ON和OFF数组,该数组的length必须大于等于2。

而DashPathEffect的第二个参数(phase)我称之为偏移值,动态改变其值会让路径产生动画的效果。

5,设置PathDashPathEffect:

这个类的作用是使用Path图形来填充当前的路径,其构造函数为PathDashPathEffect (Path shape, float advance, float phase,PathDashPathEffect.Stylestyle)。

shape则是指填充图形,advance指每个图形间的间距,phase为绘制时的偏移量,style为该类自由的枚举值,有三种情况:Style.ROTATE、Style.MORPH和
Style.TRANSLATE。

其中ROTATE的情况下,线段连接处的图形转换以旋转到与下一段移动方向相一致的角度进行转转,MORPH时图形会以发生拉伸或压缩等变形的情况与下一段相连接,TRANSLATE时,图形会以位置平移的方式与下一段相连接。

6,设置ComposePathEffect和SumPathEffect

ComposePathEffect和SumPathEffect都可以用来组合两种路径效果,就是把两种效果二合一。唯一不同的是组合的方式:

ComposePathEffect(PathEffect outerpe, PathEffect innerpe)会先将路径变成innerpe的效果,再去复合outerpe的路径效果,即:outerpe(innerpe(Path));

SumPathEffect(PathEffect first, PathEffect second)则会把两种路径效果加起来再作用于路径。

以上是关于Android PathEffect 自定义折线图必备的主要内容,如果未能解决你的问题,请参考以下文章

Android自定义组件系列——Canvas绘制折线图

Android之自定义控件实现天气温度折线图和饼状图

Android自定义view之利用PathEffect实现动态效果

Android 实现一个自定义曲线图

自定义view——折线图

Android 折线图绘制