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,一经查实,立即删除!

相关文章

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

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

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

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

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

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

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

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

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

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

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

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

前锋html5费用,足坛转会费最高的5位前锋,1.05亿欧元仅第5,第1比C罗还高1.22亿...

原标题&#xff1a;足坛转会费最高的5位前锋&#xff0c;1.05亿欧元仅第5&#xff0c;第1比C罗还高1.22亿大家都知道&#xff0c;前锋对于比赛的胜负非常重要&#xff0c;再加上其关注度比其他位置高&#xff0c;商业价值比较高&#xff0c;所以通常来说&#xff0c;他们的转会…

学计算机高中要买电脑,大一新生,打着学习的“口号”要求买电脑,父母到底该不该答应?...

原标题&#xff1a;大一新生&#xff0c;打着学习的“口号”要求买电脑&#xff0c;父母到底该不该答应&#xff1f;马上就进入9月份了&#xff0c;全国各大高校也都陆续开学。对于刚刚考上大学的大一新生来说&#xff0c;学校的一切都是很新鲜的&#xff0c;而且他们也不用像在…

计算机科学人生观和价值观,浅谈我的人生观和价值观

浅谈我的人生观和价值观2013-04-22 13:58:30 来源&#xff1a;http://www.51cok.com/ 点击:176次分享到&#xff1a;人们经常说态度决定一切&#xff0c;这就是指的人们的人生观和价值观。我们在高中学习政治哲学时开始真正地从理论上学习这一对词语&#xff0c;也是从…

添加include文件路径_-isystem以及include_next的副作用

首先我们先来看下include_next的用法比如我们想include , 在cmath头文件中你可以看到有类似include_next 的语法&#xff0c;他跟传统的include不同&#xff0c;他不会从你的search path list的头部开始查找&#xff0c;他会跳出当前路径从下一个entry进行查找&#xff0c;比如…

java防止上传恶意文件_从补丁分析到在野利用:揭秘CVE20201464 Windows文件签名验证绕过漏洞疑云...

背景2020年8月12日&#xff0c;微软发布了8月份的漏洞风险通告。通告中一个显示已被公开披露和在野利用的漏洞进入了我们的视野。该漏洞编号为CVE-2020-1464&#xff0c;其被描述为Windows验证文件数字签名时存在一个欺骗漏洞&#xff0c;攻击者若成功利用此漏洞可以绕过Window…

特殊教育学校计算机教学计划,2021年特殊教育学校教学计划

2021年特殊教育学校教学计划时间真是转瞬即逝&#xff0c;我们又将在努力中收获成长&#xff0c;现在就让我们好好地规划一下吧。那么教学计划怎么写才能体现你的真正价值呢&#xff1f;下面是小编精心整理的2021年特殊教育学校教学计划&#xff0c;希望能够帮助到大家。特殊教…

android 双层饼图_python:给表格加上双层饼图,让同事的图表黯然失色

大家好&#xff01;今天来分享一下如何用python给表格加上双层饼图&#xff0c;让同事的图表黯然失色&#xff0c;如下图所示。案例中数据表格结构如下&#xff1a;代码及演示&#xff1a;import pyecharts.options as opts from pyecharts.charts import Pie import numpy as …

计算机一级电子表格插入表格,计算机一级电子表格

电子表格一、(1)在考生文件夹下打开EXC.XLSX文件&#xff1a;①将sheet1工作表的A1&#xff1a;E1单元格合并为一个单元格&#xff0c;水平对齐方式设置为居中&#xff1b;计算各单位三种奖项的合计&#xff0c;将工作表命名为"各单位获奖情况表"。②选取"各单位…

18年高考云南628分想学计算机,2018山东高考投档线公布!山大文624理628…快查查你学校多少分进档...

原标题&#xff1a;2018山东高考投档线公布&#xff01;山大文624理628…快查查你学校多少分进档考生注意&#xff01;↓↓↓山东省2018年普通高校招生文理类本科普通批、春季高考本科、艺术类本科校考批首次志愿于7月19日投档&#xff01;具体来看&#xff0c;文理类本科普通批…

android fragment中引入自定义view_厉害了,用Android自定义View实现八大行星绕太阳3D旋转效果...

作者&#xff1a;史蒂芬诺夫斯基链接&#xff1a;https://www.jianshu.com/p/2954f2ef8ea5好久没写View了&#xff0c;最近恰巧遇到一个八大行星绕太阳旋转的假3D效果&#xff0c;写完之后感觉效果还不错。能玩十分钟的那种。本篇将一步步带您实现这样的一个效果&#xff0c;ps…

计算机消失了一个磁盘,win7系统重装后莫名奇妙消失一个分区磁盘的解决方法...

很多小伙伴都遇到过win7系统重装后莫名奇妙消失一个分区磁盘的困惑吧&#xff0c;一些朋友看过网上零散的win7系统重装后莫名奇妙消失一个分区磁盘的处理方法&#xff0c;并没有完完全全明白win7系统重装后莫名奇妙消失一个分区磁盘是如何解决的&#xff0c;今天小编准备了简单…

icloud无法验证服务器,iPhone提示“验证失败 连接到icloud时出错”怎么解决?

有不少使用苹果设备的朋友们在设备屏幕上面&#xff0c;可能会遇到了“验证失败 连接到icloud时出错”提示&#xff0c;不知道这是什么原因&#xff0c;如何解决。下面我就来谈谈出现这种现象的原因与解决办法。提示&#xff1a;“验证失败 连接到icloud时出错”&#xff0c;是…

esim办理出现差错_经营二氧化碳如何办理危化证?快来看!

点击关注我的气体网&#xff0c;置顶公众号行业资讯丨供求商机丨企业动态丨企业推荐更多信息和资源一网打尽━━━━━━安全复工二氧化碳相信大家都不陌生&#xff0c;我们平常一呼一吸间&#xff0c;呼出来的气体就是二氧化碳。还有我们平常喝的碳酸饮料&#xff0c;里边充入…

文件服务器有病毒,服务器共享文件会被病毒加密吗

前段时间纷纷扬扬的勒索病毒&#xff0c;让很多计算机用户害怕&#xff0c;就怕自己的共享文件被病毒加密而丢失&#xff0c;那么&#xff0c;服务器共享文件会被病毒加密吗&#xff1f;哪种网络条件下共享文件不易传播病毒呢&#xff1f;今天我们就跟随佰佰安全网一起来了解关…