android qq红点,Android高仿QQ小红点功能

先给大家展示下效果图:

6bbd998fd1c96c92055203b227777d6d.gif

绘制贝塞尔曲线:

041f86f0af7dc00fcce8227f6beec405.png

主要是当在一定范围内拖拽时算出固定圆和拖拽圆的外切直线以及对应的切点,就可以通过path.quadTo()来绘制二阶贝塞尔曲线了~

整体思路:

1、当小红点静止时,什么都不做,只需要给自定义小红点QQBezierView(extends TextView)添加一个.9文件当背景即可

2、当滑动时,通过getRootView()获得顶级根View,然后new一个DragView ( extends View ) 来绘制各种状态时的小红点,并且通过getRootView().addView()的方式把DragView 加进去,这样DragView 就可以实现全屏滑动了

实现过程:

自定义QQBezierView ( extends TextView ) 并复写onTouchEvent来处理各种情况,代码如下:

@Override

public boolean onTouchEvent(MotionEvent event) {

//获得根View

View 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) {

//初始化拖拽时显示的View

dragView = 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都做了哪些事呢,接下来就看一下DragView,DragView是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()) {

//在范围之内 需要RESET

startResetAnimator();

} else {

//在范围之外 消失动画

mState = STATE_DISMISS;

startExplodeAnim();

}

}

}

最后来看下DragView的onDraw方法,拖拽时的贝塞尔曲线以及拖拽滑动时的状态都是通过onDraw实现的:

@Override

protected 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) {

//绘制缓存的Bitmap

canvas.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小红点功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/528807.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

modern android5.1,Modern摩登印

Modern摩登印可以帮助小伙伴们轻松制作手机相册&#xff0c;超多素材为你提供&#xff0c;支持个性化设置&#xff0c;将照片一秒变高大上的海报&#xff0c;还能支持音乐相册效果&#xff0c;超多原创音乐随你挑选&#xff0c;结合潮流相册模板&#xff0c;让你的作品更精美哦…

android1.6,令人遗憾的Android 1.6系统_戴尔 Mini5(Streak)_手机其它OS-中关村在线

令人遗憾的Android 1.6系统虽然Dell Streak上周五刚刚在美国地区上市&#xff0c;但实际上这款产品的开发时间已经很长了。早在去年Dell的Mini 3i上市之前这款被称之为Dell Mini 5的产品就已经出现在大家的视野之中&#xff0c;而当时其搭载的就是在当时看来还是十分先进的Andr…

java第七章jdbc课后简答题_javaEE简答题答案

一、简答题(30分&#xff0c;6题*5分)(一)第一章概述1.三层体系结构的优点有哪些&#xff1f;p2(1)安全性高(2)易维护(3)快速响应(4)系统扩展灵活2.两层体系结构的缺点有哪些&#xff1f;p2-3(1)安全性低(2)部署困难(3)消耗系统资源3.简述Java EE的“组件-容器”编程思想。(P5&…

jupyter配置到服务器_服务器端jupyter notebook映射到本地浏览器的操作

&#xff11;、远程服务器上安装jupyter notebook(配置jupyter_notebook_config.py文件)sudo pip install jupyter&#xff12;、远程服务器(8890端口,没有下面括号中内容默认在服务器8888端口打开jupyter notebook&#xff0c;下面将使用默认端口8888)启动jupyter notebookjup…

android 控制word,Android使用POI进行Word操作(一)

操作步骤步骤一&#xff1a;引用相关POI库步骤二&#xff1a;创建POI中的word文件对象步骤三&#xff1a;调用word文件对象的方法对文件进行操作步骤一&#xff1a;引用相关的POI库吐槽一下&#xff0c;这一步是最坑的本人尝试了很多版本组合&#xff0c;最新的版本提示class重…

go编译so win10_windows搭建Go语言交叉编译环境

我的环境&#xff1a;64位 windows 10go version go1.9.1 windows/amd641. 安装MinGW-w64我的系统是64位win10&#xff0c;早期版本的MinGW我安装后编译go的相关工具会一路报错&#xff0c;换成mingw-w64就可以顺利编译&#xff0c;下载地址&#xff1a;http://sourceforge.net…

android car bt模块,大谷蓝牙小车BT Car/Android Car手机控制 重力控制小车 安卓操控小车...

产品介绍&#xff1a;Android蓝牙遥控小车平台。是通过Android手机以蓝牙方式操控小车前进后退左转右转等&#xff0c;具有重力感应操控、触摸屏虚拟操控、虚拟摇杆三种控制模式。并且还具有呼吸灯、电源指示灯、蓝牙连接指示灯、速度等级指示灯等状态指示。小车自带锂电池及US…

html语言怎么设计出来的,(正式)网页设计语言HTML.ppt

(正式)网页设计语言HTML第二章网页设计语言HTML HTML基础知识 页面基本信息和布局 文本修饰 超文本链接 表格 图像 表单 多媒体 什么是HTML&#xff1f; HTML是Hyper Text Markup Language的英文缩写&#xff0c;翻译为“超文本标识语言”。它是一种用来制作超文本文档的简单标…

Dijkstra(迪杰斯特拉)算法总结

知识概览 Dijkstra算法适用于解决所有边权都是正数的最短路问题。Dijkstra算法分为朴素的Dijkstra算法和堆优化版的Dijkstra算法。朴素的Dijkstra算法时间复杂度为&#xff0c;适用于稠密图。堆优化版的Dijkstra算法时间复杂度为&#xff0c;适用于稀疏图。稠密图的边数m和是一…

二元二次方程例题_二元二次方程组-解法-例题

对“二一”型二元二次方程组中形如的方程组&#xff0c;可以根据一元二次方程根与系数的关系&#xff0c;把x、y看做一元二次方程z2-azb0的两个根&#xff0c;解这个方程&#xff0c;求得的z1和z2的值&#xff0c;就是x、y的值。当x1z1时&#xff0c;y1z2&#xff1b;当x2z2时&…

wxwidget编译安装_wxWidgets的安装编译、相关配置、问题分析处理

一、介绍部分 (win7 下的 GUI 效果图见 本篇文章的最后部分截图2张)wxWidgets是一个开源的跨平台的C构架库(framework)&#xff0c;它可以提供GUI(图形用户界面)和其它工具。目前的2.x版本支持所有版本的Windows、带GTK或Motif的Unix和MacOS。相当于大家熟悉的 VC。二、wxWidge…

馀承东发布鸿蒙,鸿蒙系统一无是处?鸿蒙有何优势?

华为方面官宣&#xff0c;将于6月2日晚8点&#xff0c;举行鸿蒙操作系统及华为全场景新品发布会&#xff0c;届时&#xff0c;大家期待已久的鸿蒙操作系统也将正式亮相。鸿蒙OS有别于传统OS&#xff0c;具有四大技术特性&#xff0c;这也是鸿蒙的四大优越之处。首先&#xff0c…

html 鼠标图标做成动画效果,怎么实现鼠标经过图标动画效果

学习前端的小伙伴们你知道鼠标经过图标动画效果如何实现吗?不知道的话跟着小编一起来学习标经过图标动画效果怎么实现把。今天就为大家分享一组时尚而简单的鼠标经过图标动画效果。构建HTML基本结构在本示例当中用到的HTML结构极其简单&#xff0c;在一个大的div容器中放了几个…

netty心跳过程中 发送消息失败_Netty 4.0 实现心跳检测和断线重连

arg0.pipeline().addLast("ping", new IdleStateHandler(25, 15, 10,TimeUnit.SECONDS));这个处理器&#xff0c;它的作用就是用来检测客户端的读取超时的&#xff0c;该类的第一个参数是指定读操作空闲秒数&#xff0c;第二个参数是指定写操作的空闲秒数&#xff0c…

校验html输入值为电话号码,js验证输入是否为手机号码或电话号码示例

代码如下:String.prototype.Trim function() {var m this.match(/^\s*(\S(\s\S)*)\s*$/);return (m null) ? "" : m[1];}String.prototype.isMobile function() {return (/^(?:13\d|15[89])-?\d{5}(\d{3}|\*{3})$/.test(this.Trim()));}String.prototype.isTe…

pcs层到mac层_mac层

ETSI TS 102 887-2-2013 电磁兼容与无线频谱事务(ERM).近程设备.智能测量无线接入协议.第2部分:数据链路层(MAC子层) 版本1.1.1ETSI TS 102 887-2-2013 电磁兼容与无线频谱事务(ERM).近程设备.智能测量无线接入协议.第2部分:数据链路层(MAC子层) 版本1.1.1ETSI TS 136 321-2013…

html表格中怎么将背景颜色虚化,如何在Photoshop中制作效果惊艳模糊背景!

把背景模糊一下&#xff0c;有时&#xff0c;效果会令人非常惊艳&#xff0c;但是&#xff0c;你知道如何在Photoshop中模糊背景吗&#xff1f; 在今天的教程中&#xff0c;我们将告诉大家&#xff0c;如何使背景模糊&#xff0c;而又不会使我们的主体周围出现光晕。在这个过程…

python 切片步长_python切片步长

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":4,"count":4}]},"card":[{"des":"阿里技术人对外发布原创技术内容的最大平台&…

axure html 360安装扩展,小编搞定win7系统360浏览器添加Axure扩展的设置方案

经常使用电脑的朋友会发现win7系统360浏览器添加Axure扩展的问题比较常见&#xff0c;如今就有用户反映在使用电脑的时候遇到win7系统360浏览器添加Axure扩展的情况不知怎么解决&#xff0c;于是我就给大家整理总结了win7系统360浏览器添加Axure扩展的具体处理方案&#xff0c;…

81章 老子1章到_老子道德经第1---81章原文及译文

老子简介老子名言道德经简介道德经全文及译文道德经下载道德经全文讲解道德经朗读(道篇)|(德篇)道德经译文精简版道德经逐句翻译道德经与风水学“道”的意思人生感悟老子故里老子的思想老子的智慧老子的故事第一章[原文]道可道也①&#xff0c;非恒道也②。名可名也③&#xff…