我基本上有两条线,由我画布上的两条路径绘制。每个人只有两个点,一个应该保持静止而另一个则移动。我只是通过创建一个Path然后调用moveTo(x1,y1)和lineTo(x2,y2)来实现这一点。
(x1,y1)在时间上永远不会改变,我想在(x2,y2)改变时实现动画。
以下是我现在的代码:
public class ProgressDownload extends View {
private static final String LOG_TAG = ProgressDownload.class.getSimpleName();
private static final int STROKE_WIDTH = 10;
private static final int PADDING = 50;
private static final String BACKGROUND_COLOR = "#EC5745";
private int mWidth, mHeight;
private int mProgress;
private Path mPathBlack, mPathWhite;
private Paint mPaintBlack, mPaintWhite;
private PathEffect mPathBlackEffect, mPathWhiteEffect;
public ProgressDownload(Context context, AttributeSet attrs) {
super(context, attrs);
setBackgroundColor(Color.parseColor(BACKGROUND_COLOR));
setPadding(PADDING, 0, 50, PADDING);
mPaintBlack = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintBlack.setStyle(Paint.Style.STROKE);
mPaintBlack.setStrokeWidth(STROKE_WIDTH);
mPaintBlack.setColor(Color.BLACK);
mPaintWhite = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintWhite.setStyle(Paint.Style.STROKE);
mPaintWhite.setStrokeWidth(STROKE_WIDTH);
mPaintWhite.setColor(Color.WHITE);
mPathBlackEffect = new CornerPathEffect(10);
mPathWhiteEffect = new CornerPathEffect(10);
}
@Override
protected void onDraw(Canvas canvas) {
if(mPathWhite != null && mPathBlack != null) {
mPaintBlack.setPathEffect(mPathBlackEffect);
mPaintWhite.setPathEffect(mPathWhiteEffect);
canvas.drawPath(mPathBlack, mPaintBlack);
canvas.drawPath(mPathWhite, mPaintWhite);
}
}
@Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld) {
super.onSizeChanged(xNew, yNew, xOld, yOld);
mWidth = xNew - getPaddingRight();
mHeight = yNew;
Log.d(LOG_TAG, String.format("width and height measured are %d and %d", mWidth, mHeight));
setPercentage(0);
}
private Path makePathBlack() {
Path p = new Path();
p.moveTo(Math.max(getPaddingLeft(), mProgress*mWidth/100), mHeight/2 + calculatedeltaY());
p.lineTo(mWidth, mHeight/2);
return p;
}
private Path makePathWhite() {
Path p = new Path();
p.moveTo(getPaddingLeft(), mHeight / 2);
p.lineTo(Math.max(getPaddingLeft(), mProgress*mWidth/100), mHeight/2 + calculatedeltaY());
return p;
}
private int calculatedeltaY() {
if(mProgress <= 50) {
return (mProgress * mWidth/6)/50;
} else {
return ((100-mProgress) * mWidth/6)/50;
}
}
public void setPercentage(int percentage) {
if(percentage < 0 || percentage > 100)
throw new IllegalArgumentException("setPercentage not between 0 and 100");
mProgress = percentage;
mPathBlack = makePathBlack();
mPathWhite = makePathWhite();
invalidate();
}
}
我在路径动画中看到了很多可能性,我想我需要一些东西来更新我当前的路径到新的路径。
setPercentage()这里根据传递的值更新两个路径。目前,新旧路径之间的过渡有点“野蛮”。有关于此的任何建议吗?
答案 0 :(得分:1)
我突然开始研究对象动画师。解决方案是使用从当前百分比动画到新百分比的动画。结果正是我想要的。这是更新后的视图:
public class ProgressDownload extends View {
private static final String LOG_TAG = ProgressDownload.class.getSimpleName();
private static final int STROKE_WIDTH = 10;
private static final int PADDING = 50;
private static final long ANIMATION_DURATION = 1000;
private static final String BACKGROUND_COLOR = "#EC5745";
private int mWidth, mHeight;
private int mProgress = 0;
private Path mPathBlack, mPathWhite;
private Paint mPaintBlack, mPaintWhite;
private PathEffect mPathBlackEffect, mPathWhiteEffect;
public ProgressDownload(Context context, AttributeSet attrs) {
super(context, attrs);
setBackgroundColor(Color.parseColor(BACKGROUND_COLOR));
setPadding(PADDING, 0, 50, PADDING);
mPaintBlack = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintBlack.setStyle(Paint.Style.STROKE);
mPaintBlack.setStrokeWidth(STROKE_WIDTH);
mPaintBlack.setColor(Color.BLACK);
mPaintWhite = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintWhite.setStyle(Paint.Style.STROKE);
mPaintWhite.setStrokeWidth(STROKE_WIDTH);
mPaintWhite.setColor(Color.WHITE);
mPathBlackEffect = new CornerPathEffect(10);
mPathWhiteEffect = new CornerPathEffect(10);
}
@Override
protected void onDraw(Canvas canvas) {
if(mPathWhite != null && mPathBlack != null) {
mPaintBlack.setPathEffect(mPathBlackEffect);
mPaintWhite.setPathEffect(mPathWhiteEffect);
canvas.drawPath(mPathBlack, mPaintBlack);
canvas.drawPath(mPathWhite, mPaintWhite);
}
}
@Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld) {
super.onSizeChanged(xNew, yNew, xOld, yOld);
mWidth = xNew - getPaddingRight();
mHeight = yNew;
Log.d(LOG_TAG, String.format("width and height measured are %d and %d", mWidth, mHeight));
setPercentage(mProgress);
}
private Path makePathBlack() {
if(mPathBlack ==null) {
mPathBlack = new Path();
}
Path p = new Path();
p.moveTo(Math.max(getPaddingLeft(), mProgress*mWidth/100), mHeight/2 + calculatedeltaY());
p.lineTo(mWidth, mHeight/2);
mPathBlack.set(p);
return p;
}
private void makePathWhite() {
if(mPathWhite ==null) {
mPathWhite = new Path();
}
Path p = new Path();
p.moveTo(getPaddingLeft(), mHeight / 2);
p.lineTo(Math.max(getPaddingLeft(), mProgress * mWidth / 100), mHeight / 2 + calculatedeltaY());
mPathWhite.set(p);
}
private int calculatedeltaY() {
if(mProgress <= 50) {
return (mProgress * mWidth/6)/50;
} else {
return ((100-mProgress) * mWidth/6)/50;
}
}
public void setPercentage(int newProgress) {
if(newProgress < 0 || newProgress > 100)
throw new IllegalArgumentException("setPercentage not between 0 and 100");
ObjectAnimator anim = ObjectAnimator.ofInt(this, "progress", getProgress(), newProgress);
anim.setDuration(ANIMATION_DURATION);
anim.setInterpolator(new LinearInterpolator());
anim.start();
}
public void setProgress(int progress) {
mProgress = progress;
makePathBlack();
makePathWhite();
invalidate();
}
public int getProgress() {
return mProgress;
}
}