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

如何在Android中为正在绘制的图形设置动画,android,animation,graph,Android,Animation,Graph,我需要画线图的动画。我将收到一个值数组(可能介于0和10之间),并且随着时间的推移,该数组必须在图形上显示。我想画线图,画的应该是可见的;活泼的 我在这里看过安德斯·爱立信的教程: 代码如下: 但我似乎不能按我的方式来做 还有其他解决方案吗?以下是尝试的一般方向: 确保你对自己的工作感到满意 然后您需要创建一个新的视图(将其子类化),并覆盖onDraw方法。 此方法应仅基于动画开始后的图形部分绘制图形 我最终使用的解决方案涉及到我扩展视图的类中的一些代数 该函数从活动中获取分数数组(介于0和10

我需要画线图的动画。我将收到一个值数组(可能介于0和10之间),并且随着时间的推移,该数组必须在图形上显示。我想画线图,画的应该是可见的;活泼的

我在这里看过安德斯·爱立信的教程:

代码如下:

但我似乎不能按我的方式来做


还有其他解决方案吗?

以下是尝试的一般方向:

  • 确保你对自己的工作感到满意

  • 然后您需要创建一个新的
    视图
    (将其子类化),并覆盖
    onDraw
    方法。 此方法应仅基于动画开始后的图形部分绘制图形


  • 我最终使用的解决方案涉及到我扩展
    视图的类中的一些代数

    该函数从活动中获取分数数组(介于0和10之间的值),并使用这些值作为一行的起点和终点(请注意,一行的终点是下一行的起点)

    它计算直线的长度以及直线中有多少线段;以及在
    x
    方向上移动的距离以及在
    y
    方向上移动的方式

    然后,它计算直线中第一段末尾的
    x
    y
    值,并绘制该段

    然后将
    xDirection
    yddirection
    分别添加到
    x
    y
    点,然后再次绘制该直线,该直线现在包括该直线的第一段和第二段。这是对直线中的每个线段进行的,然后绘制从
    点A
    点B
    的最后一条直线

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

    但是,画布上根本没有绘制任何内容,因此,我现在将链接到我的另一个问题:

    但对于这个问题,我认为我最终使用的解决方案可能并没有那么糟糕。评论

    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);
    }
    
    public void setData(float[]分数、float max、int totalScores){
    Log.d(标记“从活动中获取内容”);
    分数=分数;
    numberOfScores=总分;
    Log.d(标记,“分数数=”+numberOfScores);
    maxScore=最大值;
    Log.d(标记“Max score=“+maxScore”);
    分段TODRAW=(浮动)10;
    //获取要绘制的区域的宽度
    width=Math.abs(getWidth()-getPaddingLeft()-getPaddingRight());
    //获取要绘制的区域的高度
    高度=getHeight()-getPaddingTop()-getPaddingBottom();
    Log.d(标签,“视图中的可绘制区域=”+宽度+“x”+高度);
    /*
    *现在我们开始填充一组点。
    *onDraw函数将在给定数组中绘制四个点的分组线。
    *  
    *对于第一段,我们将从第一个点的x和y开始绘制(该点将位于阵列的第一和第二个点中)
    *到第一段的x和y(将在阵列中的第3和第4个点)。
    *然后阵列中的第3和第4个点将被新的x和y取代
    *标记从第一点开始绘制的第二段的结束。
    * 
    *直到x和y不再小于直线终点的x和y时,才会发生这种情况。
    *然后,阵列中的第3和第4个点将替换为直线终点的x和y。
    * 
    *如果有更多的点需要绘制,我们阵列中的第5和第6个点也将被创建并填充
    *因为它将是绘制下一条线的前两个值(x和y),所以该线的终点的x和y。
    * 
    *所以,是的,在我们要绘制的点数组中会有重复的点,但是一组四个点将用于绘制一条线,
    *第一行的终点是第二行的起点,所以我们需要它两次。
    */     
    积分.add(getXPos(分数[0]);
    积分.add(getYPos(分数[0]);
    点数。添加((浮点)0);
    点数。添加((浮点)0);
    x=点。获取(0);
    y=点。获取(1);
    起点=分数[0];
    终点=得分[1];
    对于(int i=0;i0){
    起点=分数[i];
    终点=得分[i+1];
    x=点。获取(i*4);
    y=点。获取((i*4)+1);
    }
    startPointX=getXPos(startPoint);
    startPoint=getYPos(startPoint);
    endPointX=getXPos(endPoint);
    endPointY=getYPos(端点);
    距离线=(float)Math.sqrt(Math.pow((endPointX-startPointX),2)+Math.pow((endPointY-startPointY),2));
    Log.d(标签,“线的距离=”+线的距离);
    //获取直线中的线段数
    线段数sinline=(int)(线段/线段到绘图的距离);
    Log.d(标签,“直线段数=”+直线段数);
    //获取沿Y方向移动的距离
    yDirection=(float)((endPointY-startPointY)/(float)numberOfSegmentsInLine);
    对数d(标记“移动”+Y方向+”);
    //获取沿X方向移动的距离
    xDirection=(float)((endPointX-startPointX)/(float)numberOfSegmentsInLine);
    Log.d(标记“移动”+xDirection+“沿X方向”);
    //每个段的循环
    
    对于(intj=0;j请尝试查看倒计时或Runnable,以便onTick()或者,当发布时,你可以通过再画几个像素来更新你的线条。这可以让你画一条接一条的线条,但会产生动画效果。

    看,我不太确定该怎么做的部分是从a到B绘制线条。这必须逐点进行,但要创建一条平滑的曲线。就像绘制路径一样。我可以