android - 如何为在 Android 中绘制的图形设置动画

标签 android animation graph

我需要为折线图绘制动画。我将收到一组值(可能在 0 到 10 之间),并且必须随着时间的推移在图表上显示。我想要绘制折线图,​​并且绘图应该是可见的;动画。

我在这里查看了 Anders Ericsson 的教程:http://www.jayway.com/2012/08/29/creating-custom-android-views-part-3-animating-your-custom-views-smoothly/#comment-105813

这里的代码:https://github.com/andersericsson/ViewTutorialPart3

但我似乎无法让它按照我的方式工作。

还有其他解决方案吗?

最佳答案

我最终使用的解决方案涉及我扩展 View 的类中的一些代数。

该函数从 Activity 中获取分数数组(值介于 0 和 10 之间),并将值两两用作一条线的起点和终点(请注意,一条线的终点是起点下一行)。

它计算线的长度以及线中有多少段;还有在 x 方向上移动多远以及在 y 方向上移动多远。

然后它计算该行第一段末尾的 xy 值并绘制该段。

然后将xDirectionyDirection分别加到xy点上,画线再次,现在包括该行的第一段和第二段。对直线中的每一段都这样做,然后绘制从 point Apoint B 的最后一条直线。

但这还不完整 - setData 函数中的整个 for 循环 应该放在递归函数中,因为 postInvalidateDelayed() 不会' 暂停 for 循环 的执行。

但是, Canvas 上根本没有画任何东西,因此链接到我目前在 SO 上的另一个问题:Why are no lines drawn on my (custom View) canvas?

但是对于这个问题,我认为我最终使用的解决方案可能还不错。评论?

public void setData(float[] scorePoints, float max, int totalScores){

    Log.d(TAG, "Get stuff from activity");

    scores = scorePoints;

    numberOfScores = totalScores;
    Log.d(TAG, "Number of scores = " + numberOfScores);

    maxScore = max;
    Log.d(TAG, "Max score = " + maxScore);

    segmentToDraw = (float) 10;

    //get the width of the area to draw
    width = Math.abs(getWidth() - getPaddingLeft() - getPaddingRight());        

    //get the height of the area to draw
    height = getHeight() - getPaddingTop() - getPaddingBottom();
    Log.d(TAG, "Drawable area in view = " + width + " x " + height);    

    /*
     * Now we start filling an array of points.
     * The onDraw function will drawLines of groupings of four points in a given array.
     *  
     * For the first segment, we'll draw from the x and y of the first point (which will be in the 1st and 2nd spots in our array)
     * to the x and y of the first segment (which will be in the 3rd and 4th spots in our array). 
     * And then the 3rd and 4th spots in our array will be replaced by a new x and y 
     * marking the end of the second segment to be drawn from our first point.
     * 
     * This will happen until the x and y is not smaller than the x and y of the final point of the line, any more.
     * Then the 3rd and 4th spots in our array will be replaced by the x and y of the final point of the line.
     * 
     * If there are more points to draw, the 5th and 6th spots in our array will also be created and filled with
     * the x and y of the final point of the line because it'll be the first two values (x and y) for drawing the next line.
     * 
     * So, yes, there will be duplicates in our array of points to draw, but a grouping of four spots will be used to draw one line,
     * and the end point of the first line is the starting point of the second line, so we need it twice.
     */     

    points.add(getXPos(scores[0]));
    points.add(getYPos(scores[0]));

    points.add((float) 0);
    points.add((float) 0);

    x = points.get(0);
    y = points.get(1);

    startPoint = scores[0];
    endPoint = scores[1];

    for(int i=0; i<scores.length-1; i++){
        String thePoints = "";

        if(i>0){

            startPoint = scores[i];
            endPoint = scores[i+1];             

            x = points.get(i*4);
            y = points.get((i*4) + 1);

        }

        startPointX = getXPos(startPoint);
        startPointY = getYPos(startPoint);

        endPointX = getXPos(endPoint);
        endPointY = getYPos(endPoint);

        distanceOfLine = (float) Math.sqrt(Math.pow((endPointX - startPointX), 2) + Math.pow((endPointY - startPointY), 2)); 
        Log.d(TAG, "Distance of line = " + distanceOfLine);

        //get number of segments in line
        numberOfSegmentsInLine = (int) (distanceOfLine/segmentToDraw);
        Log.d(TAG, "Number of segments in line = " + numberOfSegmentsInLine);

        //get distance to move in Y direction
        yDirection = (float) ((endPointY - startPointY)/ (float) numberOfSegmentsInLine);
        Log.d(TAG, "Move " + yDirection + " in Y direction");

        //get distance to move in X direction
        xDirection = (float) ((endPointX - startPointX)/ (float) numberOfSegmentsInLine);
        Log.d(TAG, "Move " + xDirection + " in X direction");


            //loop for each segment
            for(int j=0; j<numberOfSegmentsInLine; j++){
                x += xDirection;
                y += yDirection;                                        

                points.set(points.size()-2, Float.valueOf(x));
                points.set(points.size()-1, Float.valueOf(y));

                Log.d(TAG, "Line : " + (i+1) + " Segment : " + j);
                Log.d(TAG, "X = "+ (x+xDirection) + " Y = " + (y+yDirection));

                Log.d(TAG, "Call invalidate now!");
                //invalidate();
                //postInvalidateDelayed(delayMilliseconds);
            }               

            //draw final line
        points.set(points.size()-2, endPointX);
        points.set(points.size()-1, endPointY);

        invalidate();
        //postInvalidateDelayed(delayMilliseconds);

        if(i<scores.length-2){

            points.add(endPointX);
            points.add(endPointY);

            points.add((float) 0);
            points.add((float) 0);
        }           

        for(int k =0; k<points.size(); k++){
            thePoints = thePoints + " : " + points.get(k);
        }
        Log.d(TAG, "Points array = " + thePoints);
    }       
}

@Override
public void onDraw(Canvas canvas){
    //setWillNotDraw(true);

    Log.d(TAG, "DRAW DAMNIT!!!");
    Log.d(TAG, "Width = " + (int) width + " Height = " + (int)height);

    paint = new Paint();
    paint.setStyle(Style.STROKE);
    paint.setStrokeWidth(4);
    paint.setColor(Color.RED);
    //paint.setAntiAlias(true);
    //paint.setShadowLayer(4, 2, 2, 0x81000000);

    Bitmap bitmap = Bitmap.createBitmap((int)width, (int)height, Bitmap.Config.ARGB_8888);
    canvas = new Canvas(bitmap);

    String drawPointsGo = "";
    float[] drawPoints = new float[points.size()];
    for(int i=0; i<points.size(); i++){
        Float f = points.get(i);
        drawPoints[i] = (float) (f != null ? f : 0.0);
        drawPointsGo = drawPointsGo + " : " + drawPoints[i];
    }
    Log.d(TAG, "Draw Points: " + drawPointsGo);

    canvas.drawLines(drawPoints, paint);
}

关于android - 如何为在 Android 中绘制的图形设置动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17088521/

相关文章:

android - java.lang.IllegalArgumentException : Host name may not be null

Android - 旋转一个按钮并停止它

c++ - 创建具有正确边的无向图

与 Kotlin、BaseObservable 和自定义委托(delegate)的 Android 数据绑定(bind)

c# - 将 Xamarin 部署到 Android 时出错

android - 如何在Android中为圆形ImageView添加阴影效果?

javascript - GameClosure: Sprite 动画

python - Matplotlib FuncAnimation 慢

Android - MPAndroidChart LineChart,无法根据值(value)日期绘制

r - R 中热图上按簇对变量进行分组