很久没更新文章了,到时候在经常浏览别人的技术文章。
现在分享一个简单实现箭头旋转指向动画。虽然在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除了产生流量外,不会产生任何付费和信息泄密。