粘性控件

来源:互联网 发布:流控绑定域名 编辑:程序博客网 时间:2024/04/28 08:35

1.粘性控件_静态绘制

1.粘性控件:对View的自定义

2.应用场景: 未读提醒的清除

3.功能实现:

   (1). 画静态图 
   (2). 把静态的数值变成变量(计算得到真实的变量)  
   (3). 不断地修改变量, 重绘界面, 动起来了.
   (4). 功能分析:
         a. 拖拽超出范围,断开, 松手, 消失
         b. 拖拽超出范围,断开,放回去了,恢复
         c. 拖拽没超出范围, 松手,弹回去

 

4.构造函数

public GooView(Context context) {this(context, null);}public GooView(Context context, AttributeSet attrs) {this(context, attrs , 0);}public GooView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle); }


5.重写onDraw方法

(1)构造函数中定义画笔

public GooView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);// 做初始化操作mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mPaint.setColor(Color.RED);}


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

/** * 粘性控件 * @author poplar * */public class GooView extends View {private static final String TAG = "TAG";private Paint mPaint;public GooView(Context context) {this(context, null);}public GooView(Context context, AttributeSet attrs) {this(context, attrs , 0);}public GooView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);// 做初始化操作mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mPaint.setColor(Color.RED);}PointF[] mStickPoints = new PointF[]{new PointF(250f, 250f),new PointF(250f, 350f)};PointF[] mDragPoints = new PointF[]{new PointF(50f, 250f),new PointF(50f, 350f)};PointF mControlPoint = new PointF(150f, 300f);PointF mDragCenter = new PointF(80f, 80f);float mDragRadius = 14f;PointF mStickCenter = new PointF(150f, 150f);float mStickRadius = 12f;private int statusBarHeight;float farestDistance = 80f;private boolean isOutofRange;private boolean isDisappear;@Overrideprotected void onDraw(Canvas canvas) {// 计算连接点值, 控制点, 固定圆半径// 1. 获取固定圆半径(根据两圆圆心距离)float tempStickRadius = getTempStickRadius();// 2. 获取直线与圆的交点float yOffset = mStickCenter.y - mDragCenter.y;float xOffset = mStickCenter.x - mDragCenter.x;Double lineK = null;if(xOffset != 0){lineK = (double) (yOffset / xOffset);}// 通过几何图形工具获取交点坐标mDragPoints = GeometryUtil.getIntersectionPoints(mDragCenter, mDragRadius, lineK);mStickPoints = GeometryUtil.getIntersectionPoints(mStickCenter, tempStickRadius, lineK);// 3. 获取控制点坐标mControlPoint = GeometryUtil.getMiddlePoint(mDragCenter, mStickCenter);// 保存画布状态canvas.save();canvas.translate(0, -statusBarHeight);// 画出最大范围(参考用)mPaint.setStyle(Style.STROKE);canvas.drawCircle(mStickCenter.x, mStickCenter.y, farestDistance, mPaint);mPaint.setStyle(Style.FILL);if(!isDisappear){if(!isOutofRange){// 3. 画连接部分Path path = new Path();// 跳到点1path.moveTo(mStickPoints[0].x, mStickPoints[0].y);// 画曲线1 -> 2path.quadTo(mControlPoint.x, mControlPoint.y, mDragPoints[0].x, mDragPoints[0].y);// 画直线2 -> 3path.lineTo(mDragPoints[1].x, mDragPoints[1].y);// 画曲线3 -> 4path.quadTo(mControlPoint.x, mControlPoint.y, mStickPoints[1].x, mStickPoints[1].y);path.close();canvas.drawPath(path, mPaint);// 画附着点(参考用)mPaint.setColor(Color.BLUE);canvas.drawCircle(mDragPoints[0].x, mDragPoints[0].y, 3f, mPaint);canvas.drawCircle(mDragPoints[1].x, mDragPoints[1].y, 3f, mPaint);canvas.drawCircle(mStickPoints[0].x, mStickPoints[0].y, 3f, mPaint);canvas.drawCircle(mStickPoints[1].x, mStickPoints[1].y, 3f, mPaint);mPaint.setColor(Color.RED);// 2. 画固定圆canvas.drawCircle(mStickCenter.x, mStickCenter.y, tempStickRadius, mPaint);}// 1. 画拖拽圆canvas.drawCircle(mDragCenter.x, mDragCenter.y, mDragRadius, mPaint);}// 恢复上次的保存状态canvas.restore();}// 获取固定圆半径(根据两圆圆心距离)private float getTempStickRadius() {float distance = GeometryUtil.getDistanceBetween2Points(mDragCenter, mStickCenter);//if(distance> farestDistance){//distance = farestDistance;//}distance = Math.min(distance, farestDistance);// 0.0f -> 1.0ffloat percent = distance / farestDistance;Log.d(TAG, "percent: " + percent);// percent , 100% -> 20% return evaluate(percent, mStickRadius, mStickRadius * 0.2f);}    public Float evaluate(float fraction, Number startValue, Number endValue) {        float startFloat = startValue.floatValue();        return startFloat + fraction * (endValue.floatValue() - startFloat);    }@Overridepublic boolean onTouchEvent(MotionEvent event) {float x;float y;switch (event.getAction()) {case MotionEvent.ACTION_DOWN:isOutofRange = false;isDisappear = false;x = event.getRawX();y = event.getRawY();updateDragCenter(x, y);break;case MotionEvent.ACTION_MOVE:x = event.getRawX();y = event.getRawY();updateDragCenter(x, y);// 处理断开事件float distance = GeometryUtil.getDistanceBetween2Points(mDragCenter, mStickCenter);if(distance > farestDistance){isOutofRange = true;invalidate();}break;case MotionEvent.ACTION_UP:if(isOutofRange){float d = GeometryUtil.getDistanceBetween2Points(mDragCenter, mStickCenter);if(d > farestDistance){// a. 拖拽超出范围,断开, 松手, 消失isDisappear = true;invalidate();}else {//b. 拖拽超出范围,断开,放回去了,恢复updateDragCenter(mStickCenter.x, mStickCenter.y);}}else {//c. 拖拽没超出范围, 松手,弹回去final PointF tempDragCenter = new PointF(mDragCenter.x, mDragCenter.y);ValueAnimator mAnim = ValueAnimator.ofFloat(1.0f);mAnim.addUpdateListener(new AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator mAnim) {// 0.0 -> 1.0ffloat percent = mAnim.getAnimatedFraction();PointF p = GeometryUtil.getPointByPercent(tempDragCenter, mStickCenter, percent);updateDragCenter(p.x, p.y);}});mAnim.setInterpolator(new OvershootInterpolator(4));mAnim.setDuration(500);mAnim.start();}break;default:break;}return true;}/** * 更新拖拽圆圆心坐标,并重绘界面 * @param x * @param y */private void updateDragCenter(float x, float y) {mDragCenter.set(x, y);invalidate();}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);statusBarHeight = Utils.getStatusBarHeight(this);}}


 

 

 

。。。。。。。。。。。。。。。。。。。。。。。。。。

0 0
原创粉丝点击