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 ...
随机推荐
- Weblogic 12c 集群部署和session复制
在上一篇Weblogic12c集群搭建的基础上,这一篇介绍Weblogic12c集群应用的部署和session复制. 1.启动服务 首先在weblogic12c控制台,启动受托管服务server1.s ...
- Python logging 模块和使用经验
记录下常用的一些东西,每次用总是查文档有点小麻烦. py2.7 日志应该是生产应用的重要生命线,谁都不应该掉以轻心 有益原则 级别分离 日志系统通常有下面几种级别,看情况是使用 FATAL - 导致程 ...
- 在OC代码中创建Swift编写的视图控制器
背景 近日在和一群朋友做项目,我和另一位同学负责iOS客户端,我是一直使用OC的,而他只会Swift,因此在我们分工协作之后,就需要把代码合在一起,这就牵扯到如何在TabbarController中添 ...
- API创建/更新员工薪水
DECLARE lb_inv_next_sal_date_warning BOOLEAN; lb_proposed_salary_warning BOOLEAN; lb_approved_warnin ...
- Android传感器概述-android学习之旅(七)
传感器概述 传感器是第二代智能手机的重要标志之一.现在许多的手机和平板都内置了传感器(tv除外).android的SDK支持许多的传感器有十几种,但是手机只是支持一部分.例如方向传感器(电子罗盘)和重 ...
- 剑指Offer--排序算法小结
剑指Offer--排序算法小结 前言 毕业季转眼即到,工作成为毕业季的头等大事,必须得认认真真进行知识储备,迎战笔试.电面.面试. 许久未接触排序算法了.平时偶尔接触到时自己会不假思索的百度,然后就是 ...
- 07 ProgressDialog
<span style="font-size:18px;">package com.fmy.example1; import android.app.Activity; ...
- 错误 frm-40654 记录已经被另一个用户更新,重新查询以查看修改
导致这问题的原因有多个,有些是最近在项目上发现不同于网上其他人遇到的 网上一般来说大家都说有如下几个原因.但是在项目上做返利时 对AP invoice 的有做更改,导致更改或插入的数据在界面上修 ...
- Swift基础用法(Swift开发之一)
昨晚苹果发布了新一代编程语言Swift,官方提供了一个iBook的说明文档,有需要的可以看下.地址:https://itunes.apple.com/cn/book/swift-programming ...
- iOS中 支付宝钱包详解/第三方支付 韩俊强的博客
每日更新关注:http://weibo.com/hanjunqiang 新浪微博! iOS开发者交流QQ群: 446310206 一.在app中成功完成支付宝支付的过程 1.申请支付宝钱包.参考网址 ...