package com.wm.remusic.widget;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.net.Uri;
import android.support.annotation.DrawableRes;
import android.util.AttributeSet;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import com.wm.remusic.R;
/**
* 圆形ImageView,可以旋转和平移
*
* @author Alan
*/
public class RoundImageView extends ImageView {
private static final int DEFAULT_DURATION = 60 * 370;
private final RectF mDrawableRect = new RectF();
private final Matrix mShaderMatrix = new Matrix();
private final Paint mBitmapPaint = new Paint();
public ObjectAnimator mObjectAnimator, mObjectAnimator1, mObjectAnimator3, defaultAinmator;
private Bitmap mBitmap;
private Bitmap srcBitmap;
private BitmapShader mBitmapShader;
private int mBitmapWidth;
private int mBitmapHeight;
private float mDrawableRadius;
private float v = 0;
// 控件默认长宽
private int defaultWidth = 0;
private int defaultHeight = 0;
public RoundImageView(Context context) {
super(context);
}
public RoundImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RoundImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
//开始旋转
public void startRotation() {
if (mObjectAnimator != null) {
if (!mObjectAnimator.isRunning()) {
mObjectAnimator.start();
}
} else {
initRotateAnimation(0f);
mObjectAnimator.start();
}
}
//停止旋转
public void stopRotation() {
if (mObjectAnimator != null) {
if (mObjectAnimator.isRunning()) {
mObjectAnimator.cancel();
}
float valueAvatar = (float) mObjectAnimator.getAnimatedValue();
v = valueAvatar;
mObjectAnimator.setFloatValues(valueAvatar, 360f + valueAvatar);
} else {
initRotateAnimation(0f);
}
}
//平移动画的准备
public void translationToLeft() {
if (mObjectAnimator != null) {
mObjectAnimator.cancel();
mObjectAnimator = null;
}
initTranlationAnimate(0, (int) (-getWidth() * 1.2));
initTranlationAnimate1(getWidth(), 0);
}
//平移动画的准备
public void translationToRight() {
mObjectAnimator.cancel();
mObjectAnimator = null;
initRotateAnimation(0f);
initTranlationAnimate(0, (int) (getWidth() * 1.2));
initTranlationAnimate1(-getWidth(), 0);
}
public boolean getAnimateState() {
return mObjectAnimator.isRunning();
}
public void initTranlationAnimate(float start, float stop) {
mObjectAnimator1 = ObjectAnimator.ofFloat(this, "translationX", start, stop);
//mObjectAnimator1.setDuration(390);
//mObjectAnimator1.setInterpolator(new LinearInterpolator());
//mObjectAnimator1.setRepeatCount(0);
}
public void initTranlationAnimate1(float start, float stop) {
mObjectAnimator3 = ObjectAnimator.ofFloat(this, "translationX", start, stop);
//mObjectAnimator3.setDuration(200);
//mObjectAnimator3.setInterpolator(new LinearInterpolator());
// mObjectAnimator3.setRepeatCount(0);
}
public void initRotateAnimation(float start) {
mObjectAnimator = ObjectAnimator.ofFloat(this, "rotation", start, 360f + start);
mObjectAnimator.setDuration(DEFAULT_DURATION);
mObjectAnimator.setInterpolator(new LinearInterpolator());
mObjectAnimator.setRepeatCount(ObjectAnimator.INFINITE);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
initRotateAnimation(0f);
initTranlationAnimate(0, getWidth());
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
// this.measure(0, 0);
if (drawable.getClass() == NinePatchDrawable.class)
return;
if (defaultWidth == 0) {
defaultWidth = getWidth();
}
if (defaultHeight == 0) {
defaultHeight = getHeight();
}
canvas.drawCircle(defaultWidth / 2, defaultHeight / 2, mDrawableRadius, mBitmapPaint);
}
@Override
public void setImageURI(Uri uri) {
super.setImageURI(uri);
mBitmap = ((BitmapDrawable) getDrawable()).getBitmap();
make(mBitmap);
}
@Override
public void setImageResource(@DrawableRes int resId) {
super.setImageResource(resId);
mBitmap = ((BitmapDrawable) getDrawable()).getBitmap();
make(mBitmap);
}
@Override
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable);
mBitmap = ((BitmapDrawable) getDrawable()).getBitmap();
make(mBitmap);
}
public Bitmap getCroppedRoundBitmap(Bitmap bmp, int radius, int borde) {
//处理传入的bitmap得到外围有黑色边的圆形bitmap
Bitmap scaledSrcBmp;
int diameter = radius * 2;
// 为了防止宽高不相等,造成圆形图片变形,因此截取长方形中处于中间位置最大的正方形图�?
int bmpWidth = bmp.getWidth();
int bmpHeight = bmp.getHeight();
int squareWidth = 0, squareHeight = 0;
int x = 0, y = 0;
Bitmap squareBitmap;
if (bmpHeight > bmpWidth) {// 高大于宽
squareWidth = squareHeight = bmpWidth;
x = 0;
y = (bmpHeight - bmpWidth) / 2;
// 截取正方形图�?
squareBitmap = Bitmap.createBitmap(bmp, x, y, squareWidth, squareHeight);
} else if (bmpHeight < bmpWidth) {// 宽大于高
squareWidth = squareHeight = bmpHeight;
x = (bmpWidth - bmpHeight) / 2;
y = 0;
squareBitmap = Bitmap.createBitmap(bmp, x, y, squareWidth, squareHeight);
} else {
squareBitmap = bmp;
}
if (squareBitmap.getWidth() != diameter || squareBitmap.getHeight() != diameter) {
scaledSrcBmp = Bitmap.createScaledBitmap(squareBitmap, diameter, diameter, true);
} else {
scaledSrcBmp = squareBitmap;
}
int width = scaledSrcBmp.getWidth();
int height = scaledSrcBmp.getHeight();
//建立返回的bitmap画布 设置长宽和属性
Bitmap output = Bitmap.createBitmap(width + 30, height + 30, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
Paint paint = new Paint();
Paint bordePaint = new Paint();
//根据图片长宽建立rect
Rect rect = new Rect(0, 0, width, height);
//圆形的画笔
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
//边界的画笔
bordePaint.setStyle(Paint.Style.STROKE);
bordePaint.setAntiAlias(true);
bordePaint.setColor(Color.BLACK);
bordePaint.setStrokeWidth(borde);
//画外围圆形
canvas.drawCircle(15 + (width / 2), 15 + (height / 2), Math.min(rect.height() / 2, rect.width() / 2), paint);
//设置图片合成用的画笔
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
//画上传入的bitmap
canvas.drawBitmap(scaledSrcBmp, 15 + (width / 2) - rect.width() / 2, 15 + (height / 2) - rect.height() / 2, paint);
//画上外边框
canvas.drawCircle((15 + width / 2), 15 + (height / 2), (width / 2) + 6, bordePaint);
//给圆形图片一个外围的图片
srcBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.play_disc);
Bitmap bitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
Paint p = new Paint();
canvas = new Canvas(bitmap);
canvas.drawARGB(0, 0, 0, 0);
p.setAntiAlias(true);
p.setFilterBitmap(true);
p.setDither(true);
//首先绘制第一张图片,很简单,就是和方法中getDstImage一样
canvas.drawBitmap(srcBitmap, 0, 0, p);
p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
canvas.drawBitmap(output, (bitmap.getWidth() - output.getWidth()) / 2, (bitmap.getHeight() - output.getHeight()) / 2, null);
return bitmap;
}
private void updateShaderMatrix() {
float scale;
float dx = 0;
float dy = 0;
mShaderMatrix.set(null);
if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
scale = mDrawableRect.height() / (float) mBitmapHeight;
dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
} else {
scale = mDrawableRect.width() / (float) mBitmapWidth;
dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
}
mShaderMatrix.setScale(scale, scale);
mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);
mBitmapShader.setLocalMatrix(mShaderMatrix);
}
private void make(Bitmap bitmap) {
mBitmap = getCroppedRoundBitmap(bitmap, 255, 15);
mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mBitmapPaint.setAntiAlias(true);
mBitmapPaint.setShader(mBitmapShader);
mDrawableRect.set(0, 0, getWidth(), getHeight());
mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2);
mBitmapHeight = mBitmap.getHeight();
mBitmapWidth = mBitmap.getWidth();
updateShaderMatrix();
invalidate();
}
}