问题
I would like to create an animation but I don't know how to get started with it. Here's this image.
I want the red and with stripes to animate from left to right. (Translate)Animations are not new to me. Moving an object on the screen is easy, because we have a background behind it. In my case it's the background that should be moving.
If I use an image then there will be no way to fill the empty space the image leaves behind while moving to the right. One idea is to fill the screen initially with the stripes programmatically, start moving them from left to right and when one starts leaving the screen then draw a new line on the left but considering the stripes are not 1px wide I don't know how to do this.
Another way would be to use an image that is wider by 2 stripes than the screen. The 2 stripes are invisible on the left. Once the image is moved to the right (end of animation), we restart the animation. I wonder if that would cause any interruption or will it look like smooth to the user.
Any ideas? Should I use andengine or something similar for this?
回答1:
You can use a custom drawable that just draws rectangles to the canvas. Following is a basic sample, just use it like
BackgroundDrawable bg = new BackgroundDrawable();
anyView.setBackground(bg);
bg.start();
Here is the basic working implementation:
public class BackgroundDrawable extends Drawable implements Runnable, Animatable {
private static final long FRAME_DELAY = 1000 / 60;
private boolean mRunning = false;
private long mStartTime;
private int mDuration = 1000;
private Paint mPaint;
private int mStripes = 7;
private void init() {
if (mPaint == null) {
mPaint = new Paint();
mPaint.setColor(Color.WHITE);
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
}
}
@Override
public void draw(Canvas canvas) {
Rect bounds = getBounds();
if (isRunning()) {
// animation in progress
final int save = canvas.save();
long timeDiff = SystemClock.uptimeMillis() - mStartTime;
canvas.clipRect(bounds);
float progress = ((float) timeDiff) / ((float) mDuration); // 0..1
float width = bounds.width() / (mStripes * 2);
for (int i = 0; i < mStripes * 2 + 2; i++) {
mPaint.setColor(i % 2 == 0 ? Color.RED : Color.WHITE);
canvas.drawRect(bounds.left + width * (i - 1) + progress * 2 * width, bounds.top, bounds.left + width * i + progress * 2* width, bounds.bottom, mPaint);
}
canvas.restoreToCount(save);
} else {
// todo draw normal
}
}
@Override
public void setBounds(int left, int top, int right, int bottom) {
super.setBounds(left, top, right, bottom);
init();
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return 0;
}
@Override
public void start() {
if (mRunning) stop();
mRunning = true;
mStartTime = SystemClock.uptimeMillis();
invalidateSelf();
scheduleSelf(this, SystemClock.uptimeMillis() + FRAME_DELAY);
}
@Override
public void stop() {
unscheduleSelf(this);
mRunning = false;
}
@Override
public boolean isRunning() {
return mRunning;
}
@Override
public void run() {
invalidateSelf();
long uptimeMillis = SystemClock.uptimeMillis();
if (uptimeMillis + FRAME_DELAY < mStartTime + mDuration) {
scheduleSelf(this, uptimeMillis + FRAME_DELAY);
} else {
mRunning = false;
start();
}
}
}
Also, I wrote a detailed explanation on drawables and basic animation handling here: Custom drawables and animations.
回答2:
You can either go for a custom view or a custom drawable and paint your stripes on a canvas in the onDraw() method
来源:https://stackoverflow.com/questions/34643048/how-to-animate-full-screen-stripes-moving-from-left-to-right