网站建设找哪里,成都三大设计院有哪些,邯郸网站建设咨询安联网络,建设网站需要了解些什么东西先给大家展示下效果图#xff1a;绘制贝塞尔曲线#xff1a;主要是当在一定范围内拖拽时算出固定圆和拖拽圆的外切直线以及对应的切点#xff0c;就可以通过path.quadTo()来绘制二阶贝塞尔曲线了~整体思路#xff1a;1、当小红点静止时#xff0c;什么都不做#xff0c;只…先给大家展示下效果图绘制贝塞尔曲线主要是当在一定范围内拖拽时算出固定圆和拖拽圆的外切直线以及对应的切点就可以通过path.quadTo()来绘制二阶贝塞尔曲线了~整体思路1、当小红点静止时什么都不做只需要给自定义小红点QQBezierView(extends TextView)添加一个.9文件当背景即可2、当滑动时通过getRootView()获得顶级根View然后new一个DragView ( extends View ) 来绘制各种状态时的小红点并且通过getRootView().addView()的方式把DragView 加进去这样DragView 就可以实现全屏滑动了实现过程自定义QQBezierView ( extends TextView ) 并复写onTouchEvent来处理各种情况代码如下Overridepublic boolean onTouchEvent(MotionEvent event) {//获得根ViewView rootView getRootView();//获得触摸位置在全屏所在位置float mRawX event.getRawX();float mRawY event.getRawY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN://请求父View不拦截getParent().requestDisallowInterceptTouchEvent(true);//获得当前View在屏幕上的位置int[] cLocation new int[2];getLocationOnScreen(cLocation);if (rootView instanceof ViewGroup) {//初始化拖拽时显示的ViewdragView new DragView(getContext());//设置固定圆的圆心坐标dragView.setStickyPoint(cLocation[0] mWidth / 2, cLocation[1] mHeight / 2, mRawX, mRawY);//获得缓存的bitmap滑动时直接通过drawBitmap绘制出来setDrawingCacheEnabled(true);Bitmap bitmap getDrawingCache();if (bitmap ! null) {dragView.setCacheBitmap(bitmap);//将DragView添加到RootView中这样就可以全屏滑动了((ViewGroup) rootView).addView(dragView);setVisibility(INVISIBLE);}}break;case MotionEvent.ACTION_MOVE://请求父View不拦截getParent().requestDisallowInterceptTouchEvent(true);if (dragView ! null) {//更新DragView的位置dragView.setDragViewLocation(mRawX, mRawY);}break;case MotionEvent.ACTION_UP:getParent().requestDisallowInterceptTouchEvent(false);if (dragView ! null) {//手抬起时来判断各种情况dragView.setDragUp();}break;}return true;}上面代码注释已经很详细了总结一下就是通过内部拦截法来请求父View是否拦截分发事件并通过event.getRawX()和event.getRawY()来不断更新DragView的位置那么DragView都做了哪些事呢接下来就看一下DragViewDragView是QQBezierView 的一个内部View类private int mState;//当前红点的状态private static final int STATE_INIT 0;//默认静止状态private static final int STATE_DRAG 1;//拖拽状态private static final int STATE_MOVE 2;//移动状态private static final int STATE_DISMISS 3;//消失状态首先声明了小红点的四种状态静止状态拖拽状态移动状态和消失状态。在QQBezierView 的onTouchEvent的DOWN事件中调用了setStickyPoint()方法/*** 设置固定圆的圆心和半径* param stickyX 固定圆的X坐标* param stickyY 固定圆的Y坐标*/public void setStickyPoint(float stickyX, float stickyY, float touchX, float touchY) {//分别设置固定圆和拖拽圆的坐标stickyPointF.set(stickyX, stickyY);dragPointF.set(touchX, touchY);//通过两个圆点算出圆心距也是拖拽的距离dragDistance MathUtil.getTwoPointDistance(dragPointF, stickyPointF);if (dragDistance maxDistance) {//如果拖拽距离小于规定最大距离则固定的圆应该越来越小这样看着才符合实际stickRadius (int) (defaultRadius - dragDistance / 10) 10 ? 10 : (int) (defaultRadius - dragDistance / 10);mState STATE_DRAG;} else {mState STATE_INIT;}}接着在QQBezierView 的onTouchEvent的MOVE事件中调用了setDragViewLocation()方法/*** 设置拖拽的坐标位置** param touchX 拖拽时的X坐标* param touchY 拖拽时的Y坐标*/public void setDragViewLocation(float touchX, float touchY) {dragPointF.set(touchX, touchY);//随时更改圆心距dragDistance MathUtil.getTwoPointDistance(dragPointF, stickyPointF);if (mState STATE_DRAG) {if (isInsideRange()) {stickRadius (int) (defaultRadius - dragDistance / 10) 10 ? 10 : (int) (defaultRadius - dragDistance / 10);} else {mState STATE_MOVE;if (onDragListener ! null) {onDragListener.onMove();}}}invalidate();}最后在QQBezierView 的onTouchEvent的UP事件中调用了setDragUp()方法public void setDragUp() {if (mState STATE_DRAG isInsideRange()) {//拖拽状态且在范围之内startResetAnimator();} else if (mState STATE_MOVE) {if (isInsideRange()) {//在范围之内 需要RESETstartResetAnimator();} else {//在范围之外 消失动画mState STATE_DISMISS;startExplodeAnim();}}}最后来看下DragView的onDraw方法拖拽时的贝塞尔曲线以及拖拽滑动时的状态都是通过onDraw实现的Overrideprotected void onDraw(Canvas canvas) {if (isInsideRange() mState STATE_DRAG) {mPaint.setColor(Color.RED);//绘制固定的小圆canvas.drawCircle(stickyPointF.x, stickyPointF.y, stickRadius, mPaint);//首先获得两圆心之间的斜率Float linK MathUtil.getLineSlope(dragPointF, stickyPointF);//然后通过两个圆心和半径、斜率来获得外切线的切点PointF[] stickyPoints MathUtil.getIntersectionPoints(stickyPointF, stickRadius, linK);dragRadius (int) Math.min(mWidth, mHeight) / 2;PointF[] dragPoints MathUtil.getIntersectionPoints(dragPointF, dragRadius, linK);mPaint.setColor(Color.RED);//二阶贝塞尔曲线的控制点取得两圆心的中点controlPoint MathUtil.getMiddlePoint(dragPointF, stickyPointF);//绘制贝塞尔曲线mPath.reset();mPath.moveTo(stickyPoints[0].x, stickyPoints[0].y);mPath.quadTo(controlPoint.x, controlPoint.y, dragPoints[0].x, dragPoints[0].y);mPath.lineTo(dragPoints[1].x, dragPoints[1].y);mPath.quadTo(controlPoint.x, controlPoint.y, stickyPoints[1].x, stickyPoints[1].y);mPath.lineTo(stickyPoints[0].x, stickyPoints[0].y);canvas.drawPath(mPath, mPaint);}if (mCacheBitmap ! null mState ! STATE_DISMISS) {//绘制缓存的Bitmapcanvas.drawBitmap(mCacheBitmap, dragPointF.x - mWidth / 2,dragPointF.y - mHeight / 2, mPaint);}if (mState STATE_DISMISS explodeIndex explode_res.length) {//绘制小红点消失时的爆炸动画canvas.drawBitmap(bitmaps[explodeIndex], dragPointF.x - mWidth / 2, dragPointF.y - mHeight / 2, mPaint);}}PS最开始使用的是 Android:clipChildren”false” 这个属性如果父View只是一个普通的ViewGroup(如LinearLayout、RelativeLayout等)此时在父View中设置android:clipChildren”false”后子View就可以超出自己的范围在ViewGroup中也可以滑动了此时也没问题但是当是RecycleView时只要ItemView设置了background属性滑动时的DragView就会显示在background的下面了好蛋疼~如有知其原因的还望不吝赐教~以上所述是小编给大家介绍的Android高仿QQ小红点功能希望对大家有所帮助如果大家有任何疑问请给我留言小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持