動畫思路:
1.首先波浪形的加載,就是貝塞爾曲線加上動畫,給上下方向和左右方向設置動畫就OK.
2.讓一個東西顯示在某張圖片或圖形之上,需要給畫筆設置PorterDuffXfermode這個類.讓其繪製公共區域,詳情參加安卓羣英傳.
porterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
3.需要用到畫布和繪製Bitmap的一些相關知識.
4.爲了動畫效果當快要充滿的時候,波浪的峯值需要遞減到一定程度.
package com.example.administrator.animationworkdemo.views;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
import android.view.View;
import com.example.administrator.animationworkdemo.R;
/**
* Created by SuperD on 2017/2/23.
*/
public class WaveLoadingView2 extends View {
private PorterDuffXfermode porterDuffXfermode;
private Paint paint;
private Bitmap bitmap;
private int width, height;
private Path path;
private Canvas mCanvas;
private Bitmap bg;
private float controlX, controlY;
private float waveY;
private boolean isIncrease;
/**
* @param context
*/
public WaveLoadingView2(Context context) {
this(context, null);
}
/**
* @param context
* @param attrs
*/
public WaveLoadingView2(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
/**
* @param context
* @param attrs
* @param defStyle
*/
public WaveLoadingView2(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
/**
* 初始化變量
*/
private void init() {
paint = new Paint();
paint.setAntiAlias(true);
paint.setDither(true);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.parseColor("#ffc9394a"));
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
width = bitmap.getWidth();
height = bitmap.getHeight();
waveY = 7 / 8F * height;
controlY = 17 / 16F * height;
porterDuffXfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
path = new Path();
mCanvas = new Canvas();
bg = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
mCanvas.setBitmap(bg);
}
@Override
protected void onDraw(Canvas canvas) {
drawTargetBitmap();
canvas.drawBitmap(bg, getPaddingLeft(), getPaddingTop(), null);
invalidate();
}
private void drawTargetBitmap() {
path.reset();
bg.eraseColor(Color.parseColor("#00ffffff"));
if (controlX >= width + 1 / 2 * width) {
isIncrease = false;
}
else if (controlX <= -1 / 2 * width) {
isIncrease = true;
}
controlX = isIncrease ? controlX + 10 : controlX - 10;
if (controlY >= 0) {
controlY -= 1;
waveY -= 1;
} else {
waveY = 7 / 8F * height;
controlY = 17 / 16F * height;
}
path.moveTo(0, waveY);
path.cubicTo(controlX / 2, waveY - (controlY - waveY),
(controlX + width) / 2, controlY, width, waveY);
path.lineTo(width, height);
path.lineTo(0, height);
path.close();
mCanvas.drawBitmap(bitmap, 0, 0, paint);
paint.setXfermode(porterDuffXfermode);
mCanvas.drawPath(path, paint);
paint.setXfermode(null);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width, height;
if (widthMode == MeasureSpec.EXACTLY) {
width = widthSize;
} else {
width = this.width + getPaddingLeft() + getPaddingRight();
if (widthMode == MeasureSpec.AT_MOST) {
width = Math.min(width, widthSize);
}
}
if (heightMode == MeasureSpec.EXACTLY) {
height = heightSize;
} else {
height = this.height + getPaddingTop() + getPaddingBottom();
if (heightMode == MeasureSpec.AT_MOST) {
height = Math.min(height, heightSize);
}
}
setMeasuredDimension(width, height);
}
}