热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android使用贝塞尔曲线仿QQ聊天消息气泡拖拽效果

这篇文章主要为大家详细介绍了Android使用贝塞尔曲线仿QQ聊天消息气泡拖拽效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Android仿QQ聊天消息气泡拖拽效果展示的具体代码,供大家参考,具体内容如下

先画圆,都会吧。代码如下:

public class Bezier extends View {
 private final Paint mGesturePaint = new Paint();
 private final Path mPath = new Path();
 private float mX1 = 100, mY1 = 150;
 private float mX2 = 300, mY2 = 150;
 private boolean mBezier = true;
 private int mRadius = 30;
 
 public Bezier(Context context, AttributeSet attrs) {
 super(context, attrs);
 mGesturePaint.setAntiAlias(true);
 mGesturePaint.setStyle(Paint.Style.FILL_AND_STROKE);
 mGesturePaint.setStrokeWidth(5);
 mGesturePaint.setColor(Color.RED);
 }
 
 @Override
 protected void onDraw(Canvas canvas) {
 // TODO Auto-generated method stub
 super.onDraw(canvas);
 canvas.drawCircle(mX1, mX2, mRadius, mGesturePaint);
 }
 
}

效果

拖拽的另个一圆就不画了,效果的实现主要是计算两个点之间的拖拽区域,如下图:

求出区域之后,使用贝塞尔线画出效果就可以了,代码:

public class Bezier extends View {
 private final Paint mGesturePaint = new Paint();
 private final Path mPath = new Path();
 private float mX1 = 100, mY1 = 150;
 private float mX2 = 300, mY2 = 150;
 private boolean mBezier = true;
 private int mRadius = 30;
 
 public Bezier(Context context, AttributeSet attrs) {
 super(context, attrs);
 mGesturePaint.setAntiAlias(true);
 mGesturePaint.setStyle(Paint.Style.FILL_AND_STROKE);
 mGesturePaint.setStrokeWidth(5);
 mGesturePaint.setColor(Color.RED);
 setBezier();
 }
 
 private void setBezier() {
 float offsetX = (float) (mRadius * Math.sin(Math.atan((mY2 - mY1) / (mX2 - mX1))));
 float offsetY = (float) (mRadius * Math.cos(Math.atan((mY2 - mY1) / (mX2 - mX1))));
 float x1 = mX1 - offsetX;
 float y1 = mY1 + offsetY;
 
 float x2 = mX2 - offsetX;
 float y2 = mY2 + offsetY;
 
 float x3 = mX2 + offsetX;
 float y3 = mY2 - offsetY;
 
 float x4 = mX1 + offsetX;
 float y4 = mY1 - offsetY;
 
 mPath.reset();
 mPath.moveTo(x1, y1);
 mPath.quadTo((mX1 + mX2) / 2, (mY1 + mY2) / 2, x2, y2);//锚点直接取偏移量的一半
 mPath.lineTo(x3, y3);
 mPath.quadTo((mX1 + mX2) / 2, (mY1 + mY2) / 2, x4, y4);
 mPath.lineTo(x1, y1);
 }
 
 @Override
 protected void onDraw(Canvas canvas) {
 // TODO Auto-generated method stub
 super.onDraw(canvas);
 //通过画布绘制多点形成的图形
 canvas.drawCircle(mX1, mY1, mRadius, mGesturePaint);
 if (mBezier) {
 canvas.drawPath(mPath, mGesturePaint);
 canvas.drawCircle(mX2, mY2, mRadius, mGesturePaint);
 }
 }
}

效果图:

拖拽效果只要在onTouchEvent里动态改变拖动点的坐标重绘就可以实现了,代码:

public class Bezier extends View {
 private final Paint mGesturePaint = new Paint();
 private final Path mPath = new Path();
 private float mX1 = 100, mY1 = 150;
 private float mX2 = 300, mY2 = 150;
 private boolean mBezier = true;
 private int mRadius = 30;
 
 public Bezier(Context context, AttributeSet attrs) {
 super(context, attrs);
 mGesturePaint.setAntiAlias(true);
 mGesturePaint.setStyle(Paint.Style.FILL_AND_STROKE);
 mGesturePaint.setStrokeWidth(5);
 mGesturePaint.setColor(Color.RED);
 setBezier();
 }
 
 private void setBezier() {
 float offsetX = (float) (mRadius * Math.sin(Math.atan((mY2 - mY1) / (mX2 - mX1))));
 float offsetY = (float) (mRadius * Math.cos(Math.atan((mY2 - mY1) / (mX2 - mX1))));
 float x1 = mX1 - offsetX;
 float y1 = mY1 + offsetY;
 
 float x2 = mX2 - offsetX;
 float y2 = mY2 + offsetY;
 
 float x3 = mX2 + offsetX;
 float y3 = mY2 - offsetY;
 
 float x4 = mX1 + offsetX;
 float y4 = mY1 - offsetY;
 
 mPath.reset();
 mPath.moveTo(x1, y1);
 mPath.quadTo((mX1 + mX2) / 2, (mY1 + mY2) / 2, x2, y2);//锚点直接取偏移量的一半
 mPath.lineTo(x3, y3);
 mPath.quadTo((mX1 + mX2) / 2, (mY1 + mY2) / 2, x4, y4);
 mPath.lineTo(x1, y1);
 }
 
 @Override
 protected void onDraw(Canvas canvas) {
 // TODO Auto-generated method stub
 super.onDraw(canvas);
 //通过画布绘制多点形成的图形
 canvas.drawCircle(mX1, mY1, mRadius, mGesturePaint);
 if (mBezier) {
 canvas.drawPath(mPath, mGesturePaint);
 canvas.drawCircle(mX2, mY2, mRadius, mGesturePaint);
 }
 }
 
 @Override
 public boolean onTouchEvent(MotionEvent event) {
 mX2 = event.getX();
 mY2 = event.getY();
 switch (event.getAction()) {
 case MotionEvent.ACTION_DOWN:
 mBezier = true;
 setBezier();
 break;
 case MotionEvent.ACTION_MOVE:
 mBezier = true;
 setBezier();
 break;
 case MotionEvent.ACTION_UP:
 mBezier = false;
 break;
 
 }
 invalidate();
 return true;
 }
 
}

源码:Android仿QQ聊天消息气泡拖拽效果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 鼠标悬停出现提示信息怎么做
    概述–提示:指启示,提起注意或给予提醒和解释。在excel中会经常用到给某个格子增加提醒信息,比如金额提示输入数值或最大长度值等等。设置方式也有多种,简单的,仅为单元格插入批注就可 ... [详细]
  • 本文将详细介绍多个流行的 Android 视频处理开源框架,包括 ijkplayer、FFmpeg、Vitamio、ExoPlayer 等。每个框架都有其独特的优势和应用场景,帮助开发者更高效地进行视频处理和播放。 ... [详细]
  • 通常情况下,修改my.cnf配置文件后需要重启MySQL服务才能使新参数生效。然而,通过特定命令可以在不重启服务的情况下实现配置的即时更新。本文将详细介绍如何在线调整MySQL配置,并验证其有效性。 ... [详细]
  • Android 6.0 切换指定 Wi-Fi 的解决方案
    本文详细介绍了在 Android 6.0 系统中切换到指定 Wi-Fi 的方法,包括常见的问题、原因分析及解决方案。通过官方文档和代码示例,帮助开发者更好地理解和实现这一功能。 ... [详细]
  • vivo Y5s配备了联发科Helio P65八核处理器,这款处理器采用12纳米工艺制造,具备两颗高性能Cortex-A75核心和六颗高效能Cortex-A55核心。此外,它还集成了先进的图像处理单元和语音唤醒功能,为用户提供卓越的性能体验。 ... [详细]
  • 深入解析 Android IPC 中的 Messenger 机制
    本文详细介绍了 Android 中基于消息传递的进程间通信(IPC)机制——Messenger。通过实例和源码分析,帮助开发者更好地理解和使用这一高效的通信工具。 ... [详细]
  • Android Studio 中查看应用程序崩溃日志的方法
    本文介绍如何在 Android Studio 中配置环境变量并使用 ADB 工具查看应用程序的崩溃日志,帮助开发者快速定位和解决问题。 ... [详细]
  • Python自动化测试入门:Selenium环境搭建
    本文详细介绍如何在Python环境中安装和配置Selenium,包括开发工具PyCharm的安装、Python环境的设置以及Selenium包的安装方法。此外,还提供了编写和运行第一个自动化测试脚本的步骤。 ... [详细]
  • 了解责任的苦与乐,是人生的重要课题。本文精选了一系列关于责任的经典语录,帮助读者更深入地理解责任感的重要性,并从中汲取力量。更多相关内容,请继续阅读。 ... [详细]
  • 本文详细介绍如何在 iOS 7 环境下申请苹果开发者账号,涵盖从访问开发者网站到最终激活账号的完整流程。包括选择个人或企业账号类型、付款方式及注意事项等。 ... [详细]
  • 本文详细介绍了如何在Android 4.4及以上版本中配置WebView以实现内容的自动高度调整和屏幕适配,确保中文显示正常,并提供代码示例。 ... [详细]
  • 解决MacOS上Android Studio Gradle版本不匹配问题
    在MacOS系统中,升级Android Studio后可能会遇到Gradle版本不兼容的问题。当网络下载更新受阻时,可以使用本地已安装的Gradle版本来解决问题。本文将详细介绍如何配置本地Gradle环境以确保开发工作的顺利进行。 ... [详细]
  • 本文介绍了如何通过Java代码计算一个整数的位数,并展示了多个基础编程示例,包括求和、平均分计算、条件判断等。 ... [详细]
  • 本题要求在一组数中反复取出两个数相加,并将结果放回数组中,最终求出最小的总加法代价。这是一个经典的哈夫曼编码问题,利用贪心算法可以有效地解决。 ... [详细]
  • 主调|大侠_重温C++ ... [详细]
author-avatar
順俟自嘫
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有