Android贝塞尔曲线实现粘性 小圆点指示器

自定义的一个粘性的指示器。

先看看效果。效果赞不赞因人而异,想更酷一些的话,可以花时间实现一下,这里就是想给大家分享一下实现的思路。

1.继承View。获取、计算 一些必要的数据。如:padding,view大小,圆点大小颜色,圆圈大小颜色,动画时间,圆点数量等。

2.获取、保存每个圆圈 的位置坐标。

3..放开选择index公共方法。调用此方法后,根据当前index和将要到达的index,获取到两个圆圈的位置坐标。启动圆圈粘性动画和圆点移动动画。

4.用ValueAnimator 从0到1,的百分百数据。根据两个点之间的总距离,算出当前位置坐标,形变程度等数据。draw出来(会画圆点和所有的圆圈)。

5.在圆点到位后,启动圆点形变复原动画。

6.动画结束后,即时改变当前index等数据。

注意点就是在动画执行完之前,用户再次选择。这个在用户选择之前判断动画是否完成,如果没完成,调用onCancel方法,onCancel中将数据即时改变。


下图可以更好的理解代码中的数据:


下面是自定义的view代码:

import java.util.ArrayList;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.BlurMaskFilter;
import android.graphics.BlurMaskFilter.Blur;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.EmbossMaskFilter;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.OvershootInterpolator;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.Animator.AnimatorListener;
import com.nineoldandroids.animation.ObjectAnimator;
import com.nineoldandroids.animation.ValueAnimator;
import com.nineoldandroids.animation.ValueAnimator.AnimatorUpdateListener;

public class BezierLinearPointsView extends View {
	// 绘制圆形贝塞尔曲线控制点的位置
	private static final float C = 0.551915024494f;

	private int mViewWidth = 0, mViewHeight = 0;
	private int mViewLeftPadding = 0, mViewRightPadding = 0,
			mViewTopPadding = 0, mViewButtomPadding = 0;

	// 点数,默认为3
	private int mCount = 3;
	// 选中小点颜色
	private int mSelectedColor = Color.GREEN;
	// 未选中小点颜色
	private int mUnSelectedColor = Color.YELLOW;
	// 小点大小
	private int mPointSize = 50;
	// 画笔宽度
	private int mPaintStrokeWidth = 6;
	// 位移动画时间
	private long mDuration = 500;
	// 恢复动画时间
	private long mDurationRe = 200;
	// 大小抖动动画时间
	private long mDurationSize = 500;
	// 是否循环
	private boolean isLooper = false;
	// 外发光宽度 是 线条宽度的几倍
	private int mBlurRadio = 2;

	// 两个圆的paint
	private Paint mUnselectedPaint, mSelectedPaint;
	private Path mPath = new Path();
	// 存放未选中点的 位置数据
	private ArrayList<int[]> mUnselectedPoints = new ArrayList<int[]>();
	// 当前位置
	private int mCurrentIndex = 0, mToIndex = 0;
	// 两个圆之间圆心距离
	private int mDis = 20;
	// 当前选中点的位置
	private int[] mCurrentPointCenter;
	// 将要选中点的位置
	private int[] mToPointCenter;
	// 动画执行进度,用来控制圆的形变程度
	private float mPercent = 0f;
	// 反弹动画执行进度,用来控制圆的复原形变程度
	private float mRePercent = 0f;
	// 圆圈从未选中到选中抖动动画程度
	private float mSizePercent = 1f;
	// 圆形的控制点与数据点的差值
	private float mDifference;
	// 顺时针记录绘制圆形的四个数据点
	private float[] mData = new float[8];
	// 顺时针记录绘制圆形的八个控制点
	private float[] mCtrl = new float[16];
	// 来标识形变 恢复的时候是改动哪个点。0:两点相同,不变。1:index增加恢复,更改的是圆的左点。-1:index减少恢复,更改圆右点
	private int isIndexInCreate = 0;

	// 位移动画
	private ValueAnimator va;
	// 恢复动画
	private ValueAnimator vaRe;
	// 圆圈从 选中到不选中,粘性动画
	private ValueAnimator vaSize;

	public BezierLinearPointsView(Context context) {
		super(context);
		init(context, null);
	}

	public BezierLinearPointsView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context, attrs);
	}

	public BezierLinearPointsView(Context context, AttributeSet attrs,
			int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		init(context, attrs);
	}

//	public BezierLinearPointsView(Context context, AttributeSet attrs,
//			int defStyleAttr, int defStyleRes) {
//		super(context, attrs, defStyleAttr, defStyleRes);
//		init(context, attrs);
//	}

	/**
	 * 初始化一些
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值