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