Java Android中带动画的淡入边缘/遮罩
我创建了一个动画,显示了多辆汽车向上行驶。动画如下图所示: 这个动画需要放在谷歌地图片段的顶部,汽车必须在顶部和底部淡出 现在,我使用关键帧实现了这一点,我手动创建了15个图像,这些图像依次显示以创建此效果 问题是我只是使用ObjectAnimator创建动画,并在代码中生成淡入淡出的边,这样我就可以轻松地更改动画 当我需要的时候,给我一张汽车的照片 我尝试使用以下代码解决我的问题:Java Android中带动画的淡入边缘/遮罩,java,android,google-maps,android-studio,Java,Android,Google Maps,Android Studio,我创建了一个动画,显示了多辆汽车向上行驶。动画如下图所示: 这个动画需要放在谷歌地图片段的顶部,汽车必须在顶部和底部淡出 现在,我使用关键帧实现了这一点,我手动创建了15个图像,这些图像依次显示以创建此效果 问题是我只是使用ObjectAnimator创建动画,并在代码中生成淡入淡出的边,这样我就可以轻松地更改动画 当我需要的时候,给我一张汽车的照片 我尝试使用以下代码解决我的问题: public class MaskView extends View { private Bitmap
public class MaskView extends View {
private Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.car);
private float topStart = -bitmap.getHeight();
private float top = 0; // Don't change!
//private final float margin = Util.convertDpToPixel(5f, getContext());
private final int smoothness = 10;
private final float speed = bitmap.getHeight() / 20;
private LinearGradient linearGradient = null;
private Paint defaultPaint;
private Paint maskPaint;
private Path maskPath;
public MaskView(Context context) {
super(context);
init();
}
public MaskView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
int width = getMeasuredWidth();
int halfWidth = width / 2;
int height = getMeasuredHeight();
linearGradient = new LinearGradient(halfWidth, 0, halfWidth, height, new int[] {
Color.parseColor("#00000000"), Color.parseColor("#CC000000"), Color.parseColor("#CC000000"), Color.parseColor("#00000000")}, new float[] {0f, 0.3f, 0.7f, 1f}, Shader.TileMode.CLAMP);
defaultPaint = new Paint();
defaultPaint.setStyle(Paint.Style.FILL);
defaultPaint.setColor(Color.parseColor("#FF000000"));
maskPaint = new Paint();
maskPaint.setStyle(Paint.Style.FILL);
maskPaint.setColor(Color.parseColor("#FF000000"));
maskPaint.setShader(linearGradient);
maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
maskPath = new Path();
maskPath.moveTo(0, 0);
maskPath.lineTo(width, 0);
maskPath.lineTo(width, height);
maskPath.lineTo(0, height);
maskPath.lineTo(0, 0);
}
private void init() {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
post(new Runnable() {
@Override
public void run() {
if(topStart < 0f) {
topStart += speed;
}
else
topStart = -bitmap.getHeight(); // Reset
invalidate();
postDelayed(this, smoothness);
}
});
}
@Override
protected void onDraw(Canvas canvas) {
if(linearGradient == null) return;
top = topStart;
while(top < canvas.getHeight())
{
canvas.drawBitmap(bitmap, 0, top, null);
top += bitmap.getHeight();
}
canvas.drawPath(maskPath, maskPaint);
}
}
使用这个简单的实现(您可以在
onTimeUpdate
listener中调整速度,现在一辆车每秒向上移动):
编辑:
要使用此pre JELLY_BEAN:
格拉德尔:
编译'com.ninealdroids:library:2.4.0+'
类别:
导入com.nineodeldroids.animation.TimeAnimator 使用
ObjectAnimator
/ValueAnimator
而不是Handler
,整体效果会更好谢谢,我更新了我的问题抱歉,我没有注意到它的无限动画,也许TimeAnimator会更好?TimeAnimator感觉比ValueAnimator差。但也许我用错了,试试看
final ValueAnimator va = ValueAnimator.ofFloat(-bitmap.getHeight() - margin, 0f);
va.setInterpolator(new LinearInterpolator());
va.setDuration(smoothness);
va.setRepeatMode(ValueAnimator.INFINITE);
va.setRepeatCount(ValueAnimator.INFINITE);
a.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
topStart = value;
invalidate();
}
});
va.start();
public class MaskView extends View implements TimeAnimator.TimeListener {
private Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.car);
private float y;
private Paint carPaint = new Paint();
private Paint maskPaint = new Paint();
private Rect carRect = new Rect();
public MaskView(Context context) {
super(context);
init();
}
public MaskView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
int colors[] = {0x00000000, 0xff000000, 0xff000000, 0x00000000};
float[] positions = {0f, 0.3f, 0.7f, 1f};
maskPaint.setShader(new LinearGradient(0, 0, bitmap.getWidth(), h, colors, positions, Shader.TileMode.CLAMP));
maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
carPaint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.REPEAT));
carRect.set(0, 0, bitmap.getWidth(), h + bitmap.getHeight());
}
private void init() {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
TimeAnimator animator = new TimeAnimator();
animator.setTimeListener(this);
animator.start();
}
@Override
protected void onDraw(Canvas canvas) {
canvas.translate(0, -y);
canvas.drawRect(carRect, carPaint);
canvas.translate(0, y);
canvas.drawRect(carRect, maskPaint);
}
@Override
public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
y = (bitmap.getHeight() * totalTime / 1000f) % bitmap.getHeight();
invalidate(carRect);
}
}