多看多学涨姿势,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开源项目的学习的更多相关文章

  1. Android 开源项目及其学习

    Android 系统研究:http://blog.csdn.net/luoshengyang/article/details/8923485 Android 腾讯技术人员博客 http://hukai ...

  2. 开源项目live555学习心得

      推荐:伊朗美女找丈夫比找工作难女人婚前一定要看清三件事 × 登录注册   疯狂少男-IT技术的博客 http://blog.sina.com.cn/crazyboyzhaolei [订阅][手机订 ...

  3. 一个toolkit或者一个开源项目如何学习它并使用它

    一个toolkit或者一个开源项目如何学习它并使用它 一般一个流行的toolkit和开源项目,一般都会被广泛地被应用: 那么,我们如何学习它,如何应用它在自己的业务场景中呢? 答案就是:学习源码并借鉴 ...

  4. iOS及Mac开源项目和学习资料【超级全面】

    UI 下拉刷新 EGOTableViewPullRefresh – 最早的下拉刷新控件. SVPullToRefresh – 下拉刷新控件. MJRefresh – 仅需一行代码就可以为UITable ...

  5. iOS开发--iOS及Mac开源项目和学习资料

    文/零距离仰望星空(简书作者)原文链接:http://www.jianshu.com/p/f6cdbc8192ba著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 原文出处:codecl ...

  6. 开源项目AndroidReview学习小结(1)

    多看多学涨姿势 最近学习了一个开源项目,感觉收获颇多,这里做下简要的记录,首先感谢作者的开源.先看个大概图 感觉框架非常简单,界面也很一般,不过底层的处理的一些处理还是有很多可圈可点之处,代码的处理一 ...

  7. 开源项目AndroidReview学习小结(2)

    读书破万卷下笔如有神 作为入门级的android码农的我,还是需要多多研读开源代码 下面继续接着上一篇的分析,这一篇主要介绍第一个tab,ReviewFragment的分析,界面看起来简单,背后的逻辑 ...

  8. Android开源项目SlidingMenu学习(二)

    前一篇SlidingMenu学习(一)文章中了解了导入SlidingMenu到我们项目经常出现的问题,下面我们正式学习. 先看一个效果: 看到两幅图片的差别了吗,左边的一栏时可以滑动的,可以隐藏掉,现 ...

  9. 分享海量 iOS 及 Mac 开源项目和学习资料

    UI 下拉刷新 EGOTableViewPullRefresh - 最早的下拉刷新控件. SVPullToRefresh - 下拉刷新控件. MJRefresh - 仅需一行代码就可以为UITable ...

随机推荐

  1. React Native自定义导航条

    Navigator和NavigatorIOS 在开发中,需要实现多个界面的切换,这时候就需要一个导航控制器来进行各种效果的切换.在React Native中RN为我们提供了两个组件:Navigator ...

  2. Leetcode解题-树(5.0.0)基础类

    与第二章类似,LeetCode指定了TreeNode实现.为了方便后续习题的编写和测试,创建一个基础父类,包含TreeNode实现,以及create()和print()创建和打印树的方法.其中crea ...

  3. Android倒计时器——CountDownTimer

    Android倒计时器--CountDownTimer 说明 第一个参数是倒计时的时间 第二个参数是多长时间执行一次回调 /** * @param millisInFuture The number ...

  4. SpriteKit游戏Delve随机生成地牢地图一个Bug的修复

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) Delve是一个很有意思的地牢探险类型的游戏,其中每一关的地图 ...

  5. Dynamics CRM 开启EmailRouter日志记录

    找到mailrouter的安装路径,在service文件夹下找到"Microsoft.Crm.Tools.EmailAgent.xml"这个文件,已管理员方式打开,找到loglev ...

  6. 存储那些事儿(二): 下一代Linux文件系统BTRFS简介

    BTRFS,通常念成 Butter FS,Better FS 或B-tree FS.下一代的Linux文件系统. 它基于写时拷贝(copy-on-write),支持高效的snapshot和clone. ...

  7. 在maven中开发Spring需要的jar依赖

    在maven中开发Spring需要的jar依赖 <properties> <spring.version>4.0.6.RELEASE</spring.version> ...

  8. Linux Debugging(二): 熟悉AT&T汇编语言

    没想到<Linux Debugging:使用反汇编理解C++程序函数调用栈>发表了收到了大家的欢迎.但是有网友留言说不熟悉汇编,因此本书列了汇编的基础语法.这些对于我们平时的调试应该是够用 ...

  9. 【Unity 3D 游戏开发】Unity3D 入门 - 工作区域介绍 与 入门示例

    一. 工作区域详解 1. Scence视图 (场景设计面板) scence视图简介 : 展示创建的游戏对象, 可以对所有的游戏对象进行 移动, 操作 和 放置; -- 示例 : 创建一个球体, 控制摄 ...

  10. UILTView经典知识点练习

    作者:韩俊强   未经允许,请勿转载! 关注博主:http://weibo.com/hanjunqiang 声明:UILTView 指:UILabel 和 UITextField 的复合 #impor ...