很久没更新文章了,到时候在经常浏览别人的技术文章。
现在分享一个简单实现箭头旋转指向动画。虽然在actionbar里面实现很简单,但自己还是用代码写了。供大家分享。
转发请著名: http://androidmaster.iteye.com/blog/2335021
DrawerArrowDrawable.java
package com.jinwowo.android.widget;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.animation.DecelerateInterpolator;
import com.jinwowo.android.R;
public abstract class DrawerArrowDrawable extends Drawable {
private static final float ARROW_HEAD_ANGLE = (float) Math.toRadians(45.0D); // 箭头的角度
protected float mBarGap; // 菜单 按钮两条线之间的间隔
protected float mBarSize; // 菜单 按钮线的长度
protected float mBarThickness; // 菜单按钮 线的宽度
protected float mMiddleArrowSize; // 箭头按钮 中间那条线的长度
protected final Paint mPaint = new Paint();
protected final Path mPath = new Path();
protected float mProgress;
protected float cmProgress;
protected int mSize;
protected float mVerticalMirror = 1f;
protected float mTopBottomArrowSize;// 箭头 按钮的上下部分的长度
protected Context context;
public DrawerArrowDrawable(Context context) {
this.context = context;
this.mPaint.setAntiAlias(true);// 设置抗锯齿
this.mPaint.setColor(context.getResources().getColor(R.color.white)); // 设置画笔的颜色为白色
this.mSize = context.getResources().getDimensionPixelSize(R.dimen.ldrawer_drawableSize);
this.mBarSize = context.getResources().getDimensionPixelSize(R.dimen.ldrawer_barSize);
this.mTopBottomArrowSize = context.getResources().getDimensionPixelSize(R.dimen.ldrawer_topBottomBarArrowSize);
this.mBarThickness = context.getResources().getDimensionPixelSize(R.dimen.ldrawer_thickness);
this.mBarGap = context.getResources().getDimensionPixelSize(R.dimen.ldrawer_gapBetweenBars);
this.mMiddleArrowSize = context.getResources().getDimensionPixelSize(R.dimen.ldrawer_middleBarArrowSize);
this.mPaint.setStyle(Paint.Style.STROKE);
// 设置两条线相交时候 相交部分的处理
this.mPaint.setStrokeJoin(Paint.Join.ROUND);
this.mPaint.setStrokeCap(Paint.Cap.SQUARE);
// 设置画笔线的宽度
this.mPaint.setStrokeWidth(this.mBarThickness);
}
// 此方法是用来进行动画转换的时候差值的 第三个参数是进度
protected float lerp(float paramFloat1, float paramFloat2, float paramFloat3) {
return paramFloat1 + paramFloat3 * (paramFloat2 - paramFloat1);
}
PathMeasure mpMeasure;
public void draw(Canvas canvas) {
Rect localRect = getBounds();
float f1 = lerp(this.mBarSize, this.mTopBottomArrowSize, this.mProgress);
float f2 = lerp(this.mBarSize, this.mMiddleArrowSize, this.mProgress);
float f3 = lerp(0.0F, this.mBarThickness / 2.0F, this.mProgress);
float f4 = lerp(0.0F, ARROW_HEAD_ANGLE, this.mProgress);
float f5 = 0.0F;
float f6 = 180.0F;
float f7 = lerp(f5, f6, this.mProgress);
float f8 = lerp(this.mBarGap + this.mBarThickness, 0.0F, this.mProgress);
this.mPath.rewind();
float f9 = -f2 / 2.0F;
this.mPath.moveTo(f9 + f3, 0.0F);
this.mPath.rLineTo(f2 - f3, 0.0F);
float f10 = (float) Math.round(f1 * Math.cos(f4));
float f11 = (float) Math.round(f1 * Math.sin(f4));
this.mPath.moveTo(f9, f8);
this.mPath.rLineTo(f10, f11);
this.mPath.moveTo(f9, -f8);
this.mPath.rLineTo(f10, -f11);
this.mPath.moveTo(0.0F, 0.0F);
this.mPath.close();
canvas.save();
if (!isLayoutRtl())
canvas.rotate(180.0F, localRect.centerX(), localRect.centerY());
canvas.rotate(f7 * mVerticalMirror, localRect.centerX(), localRect.centerY());
canvas.translate(localRect.centerX(), localRect.centerY());
canvas.drawPath(this.mPath, this.mPaint);
canvas.restore();
}
// 开启路径动画
public void startPathAnim() {
if (mProgress == cmProgress) {
return;
}
// 0 - getLength()
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 10);
valueAnimator.setDuration(1000);
// 减速插值器
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (Float) animation.getAnimatedValue();
if (cmProgress == 1) {
mProgress = value / 10f;
invalidateSelf();
} else { // 0
mProgress = 1 - value / 10f;
invalidateSelf();
}
Log.e("TAG", value + "");
// 获取当前点坐标封装到mCurrentPosition
// mpMeasure.getPosTan(value, mCurrentPosition, null);
// postInvalidate();
// invalidateSelf();
}
});
valueAnimator.start();
}
public int getIntrinsicHeight() {
return this.mSize;
}
public int getIntrinsicWidth() {
return this.mSize;
}
public void setAlpha(int alpha) {
this.mPaint.setAlpha(alpha);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
public abstract boolean isLayoutRtl();
public void setColorFilter(ColorFilter colorFilter) {
this.mPaint.setColorFilter(colorFilter);
}
public void setVerticalMirror(boolean mVerticalMirror) {
this.mVerticalMirror = mVerticalMirror ? 1 : -1;
}
/**
* 实现旋转动画。
*
* @param paramFloat
* 0 .1
*/
public void setProgress(float paramFloat) {
// this.mProgress = paramFloat;
this.cmProgress = paramFloat;
// invalidateSelf();
startPathAnim();
}
public void setColor(int resourceId) {
this.mPaint.setColor(context.getResources().getColor(resourceId));
}
}
调用方法:imgUserHead为ImageView
final DrawerArrowDrawable drawable = new DrawerArrowDrawable(this.getCurtentActivity()) {
@Override
public boolean isLayoutRtl() {
return false;
}
};
imgUserHead.setImageDrawable(drawable);
imgUserHead.setOnClickListener(new OnClickListener() {
boolean isclick = false;
@Override
public void onClick(View arg0) {
isclick = !isclick;
if (isclick) {
drawable.setProgress(0f);
} else {
drawable.setProgress(1f);
}
}
});
效果图:
下次分享:
欢迎大家扫描二维码加我,下载App体验使用。声明:下载App除了产生流量外,不会产生任何付费和信息泄密。