BezierDemo开源项目的学习
多看多学涨姿势,no zuo nuo die做暖男
1、概述
国际惯例,首先感谢一下开源作者。
这个项目主要是实现实现qq红点拖拽的效果 地址在https://github.com/chenupt/BezierDemo
主要效果
梳理主要知识点
【1】贝塞尔曲线的使用
【2】动态添加view
【3】判断点击事件是否在指定区域
2、项目知识点分析
【2.1】贝塞尔曲线的使用
常用的有2阶贝塞尔曲线
Path方法中
quadTo(float x1, float y1, float x2, float y2)可以用来绘制2阶贝塞尔曲线
其中quadTo的前两个参数为控制点的坐标,后两个参数为终点坐标,至于起点默认是画布的左上角。通常我们会使用moveTo移动到我们需要的起点,这里的p0就是起点,(x1,y1)就是中点P1,(x2,y2)就是末端点P2。p1称之为锚点
还有三阶贝塞尔曲线
同样是Path方法中
cubicTo(float x1, float y1, float x2, float y2, float x3, float y3) 用来绘制三阶贝塞尔曲线
与quadTo类似,前四个参数表示两个控制点,最后两个参数表示终点。其实,(x1,y1)就是P1,(x2,y2)是P2,(x3,y3)是P3。p2,p3称之为锚点
【在该项目中的使用】
项目中使用二阶贝塞尔曲线,由于实现拖拽效果实际是固定一个点,拖拽过程中为一个点,发生贝塞尔曲线实际上为这俩个圆之间的切线,如下图
可以看出p1-p2和p3-p4俩条线段会产生贝塞尔曲线,锚点在圆心连线上
作者在calcute方法中做了处理
// 根据角度算出四边形的四个点 float offsetX = (float) (radius*Math.sin(Math.atan((y - startY) / (x - startX)))); float offsetY = (float) (radius*Math.cos(Math.atan((y - startY) / (x - startX)))); float x1 = startX - offsetX; float y1 = startY + offsetY; float x2 = x - offsetX; float y2 = y + offsetY; float x3 = x + offsetX; float y3 = y - offsetY; float x4 = startX + offsetX; float y4 = startY - offsetY; path.reset(); path.moveTo(x1, y1); path.quadTo(anchorX, anchorY, x2, y2); path.lineTo(x3, y3); path.quadTo(anchorX, anchorY, x4, y4); path.lineTo(x1, y1);
【2.2、动态添加view】
这里牵涉到LayoutParams
LayoutParams继承于Android.View.ViewGroup.LayoutParams.
LayoutParams相当于一个Layout的信息包,它封装了Layout的位置、高、宽等信息。假设在屏幕上一块区域是由一个Layout占领的,如果将一个View添加到一个Layout中,最好告诉Layout用户期望的布局方式,也就是将一个认可的layoutParams传递进去。
但LayoutParams类也只是简单的描述了宽高,宽和高都可以设置成三种值:
1,一个确定的值;
2,FILL_PARENT,即填满(和父容器一样大小);
3,WRAP_CONTENT,即包裹住组件就好。
作者动态添加了俩个imageview,一个是表示消息的imageview一个是移除红点之后的气泡效果
在Init方法中
LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); exploredImageView = new ImageView(getContext()); exploredImageView.setLayoutParams(params); exploredImageView.setImageResource(R.drawable.tip_anim); exploredImageView.setVisibility(View.INVISIBLE); tipImageView = new ImageView(getContext()); tipImageView.setLayoutParams(params); tipImageView.setImageResource(R.drawable.skin_tips_newmessage_ninetynine); addView(tipImageView); addView(exploredImageView);
通过LayoutParams + addView完成动态添加控件,其实有时候xml无法满足时我们也可以通过动态控制view的方式来解决问题,建议还是熟悉一下代码写常用布局。
这里补充一下:
exploredImageView使用的是帧动画AnimationDrawable,这样可以模拟出连续的效果,使用也很简单,在drable文件夹中定义几个帧动画
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true"> <item android:drawable="@drawable/idp" android:duration="300"/> <item android:drawable="@drawable/idq" android:duration="300"/> <item android:drawable="@drawable/idr" android:duration="300"/> <item android:drawable="@drawable/ids" android:duration="300"/> <item android:drawable="@drawable/idt" android:duration="300"/> <item android:drawable="@android:color/transparent" android:duration="300"/> </animation-list>
这样可以模拟出消息移除后气泡爆炸的效果
【2.3、判断点击事件是否在指定区域】
主要是使用到
View.getLocationInWindow(int[] location)
一个控件在其父窗口中的坐标位置
View.getLocationOnScreen(int[] location)
一个控件在其整个屏幕上的坐标位置
他们使用的模式都一样先new一个Rect
该项目中需要判断点击事件是否是在红色消息图片上
if(event.getAction() == MotionEvent.ACTION_DOWN){ // 判断触摸点是否在tipImageView中 Rect rect = new Rect(); int[] location = new int[2]; tipImageView.getDrawingRect(rect); tipImageView.getLocationOnScreen(location); rect.left = location[0]; rect.top = location[1]; rect.right = rect.right + location[0]; rect.bottom = rect.bottom + location[1]; if (rect.contains((int)event.getRawX(), (int)event.getRawY())){ isTouch = true; }
BezierDemo开源项目的学习的更多相关文章
- Android 开源项目及其学习
Android 系统研究:http://blog.csdn.net/luoshengyang/article/details/8923485 Android 腾讯技术人员博客 http://hukai ...
- 开源项目live555学习心得
推荐:伊朗美女找丈夫比找工作难女人婚前一定要看清三件事 × 登录注册 疯狂少男-IT技术的博客 http://blog.sina.com.cn/crazyboyzhaolei [订阅][手机订 ...
- 一个toolkit或者一个开源项目如何学习它并使用它
一个toolkit或者一个开源项目如何学习它并使用它 一般一个流行的toolkit和开源项目,一般都会被广泛地被应用: 那么,我们如何学习它,如何应用它在自己的业务场景中呢? 答案就是:学习源码并借鉴 ...
- iOS及Mac开源项目和学习资料【超级全面】
UI 下拉刷新 EGOTableViewPullRefresh – 最早的下拉刷新控件. SVPullToRefresh – 下拉刷新控件. MJRefresh – 仅需一行代码就可以为UITable ...
- iOS开发--iOS及Mac开源项目和学习资料
文/零距离仰望星空(简书作者)原文链接:http://www.jianshu.com/p/f6cdbc8192ba著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 原文出处:codecl ...
- 开源项目AndroidReview学习小结(1)
多看多学涨姿势 最近学习了一个开源项目,感觉收获颇多,这里做下简要的记录,首先感谢作者的开源.先看个大概图 感觉框架非常简单,界面也很一般,不过底层的处理的一些处理还是有很多可圈可点之处,代码的处理一 ...
- 开源项目AndroidReview学习小结(2)
读书破万卷下笔如有神 作为入门级的android码农的我,还是需要多多研读开源代码 下面继续接着上一篇的分析,这一篇主要介绍第一个tab,ReviewFragment的分析,界面看起来简单,背后的逻辑 ...
- Android开源项目SlidingMenu学习(二)
前一篇SlidingMenu学习(一)文章中了解了导入SlidingMenu到我们项目经常出现的问题,下面我们正式学习. 先看一个效果: 看到两幅图片的差别了吗,左边的一栏时可以滑动的,可以隐藏掉,现 ...
- 分享海量 iOS 及 Mac 开源项目和学习资料
UI 下拉刷新 EGOTableViewPullRefresh - 最早的下拉刷新控件. SVPullToRefresh - 下拉刷新控件. MJRefresh - 仅需一行代码就可以为UITable ...
随机推荐
- MPAndroidChart图形联动
MPAndroidChart图形联动 本篇基于博客MPAndroidChart的K线图上添加均线,两个MPAndroidChart是有联动效果的 原理 获取正在滑动的Chart的触摸事件,将事件同步给 ...
- springMVC源码分析--HandlerMethod
在之前的博客中我们已经接触过HandlerMethod,接下来我们简单介绍一下HandlerMethod,简单来说HandlerMethod包含的信息包括类.方法和参数的一个信息类,通过其两个构造函数 ...
- React Native组件只Image
不管在Android还是在ios原生的开发中,图片都是作为控件给出来的,在RN中也有这么一个控件(Image).根据官网的资料,图片分为本地静态图片,网络图片和混合app资源.一下分类介绍来源官网. ...
- SSO 基于Cookie+fliter实现单点登录 实例解析(一)
接上文,SSO的理论讲解,接下来实践实践! 1.使用Cookie解决单点登录 技术点: 1.设置Cookie的路径为setPath("/").即Tomcat的目录下都有效 2.设置 ...
- Android动态换肤(三、安装主题apk方式)
相比之前免安装的方式,这种方法需要用户下载并安装皮肤apk,程序写起来比免安装的要简单很多,像很多系统主题就是通过这种方式实现的. 这种方式的思路是,从所有已安装的应用程序中遍历出皮肤程序(根据特定包 ...
- 3.关于QT中的MainWindow窗口,MenuBar,ToolBar,QuickTip等方面的知识点
1 新建一个空Qt项目 编写12MainWindow.pro HEADERS += \ MyMainWindow.h \ MyView.h SOURCES += \ MyMainWindow.c ...
- 自定义gradview
http://blog.csdn.net/jdsjlzx/article/details/7525724 虽然Android已自带了GridView,但是,却不够灵活,同时也不能自由添加控件,因此,本 ...
- ios zxing扫码问题
在ios 中 扫瞄二维码,条形码基本有 2中第三方的库,一个是zbar 一个是zxing,zxing 在android中表现的比较出色,但是在ios 中不是很好用,扫瞄效率低,我们一般都用zbar,但 ...
- Android支持多国语言化Values命名
android多国语言文件夹文件汇总如下: 维吾尔文(中国):values-ug-rCN 中文(中国):values-zh-rCN 中文(台湾):values-zh-rTW 中文(香港):values ...
- 【安卓中的缓存策略系列】安卓缓存策略之磁盘缓存DiskLruCache
安卓中的缓存包括两种情况即内存缓存与磁盘缓存,其中内存缓存主要是使用LruCache这个类,其中内存缓存我在[安卓中的缓存策略系列]安卓缓存策略之内存缓存LruCache中已经进行过详细讲解,如看官还 ...