wing带你玩转自定义view系列(1) 仿360内存清理效果

本篇是接自 手把手带你做自定义view系列

宗旨都是一样,带大家一起来研究自定义view的实现,与其不同的是本系列省去了简单的坐标之类的讲解,重点在实现思路,用简洁明了的文章,来与大家一同一步步学习。

转载请注明出处:http://blog.csdn.net/wingichoy/article/details/50500479

上一篇介绍了:神奇的贝塞尔曲线,这篇就来研究其应用。

我自己的学习方法是:学习了贝塞尔曲线之后,去研究他的规律,然后开始联想有没有见过类似的效果,最后自己去研究实现,在没有遇到绝对困难的时候,独立思考。只有遇到了绝对困难或者做出来效果之后,才去参考其他人的做法。

好了,废话不多说了,来看看效果图:

图片是从360安全卫士apk里面解压的。一张背景图,一张小绿的图片。

先定义一些属性

private int mWidth;
    private int mHeight;
    //线的Y坐标
    private int mLineY = 600;
    //判断是否画线回弹
    private boolean isDrawBack = false;

    private int mBitmapX;
    private int mBitmapY;

    //飞行的百分比
    private int mFlyPercent = 100;
    //辅助点坐标 x坐标为线段中点,
    Point supPoint = new Point(350, mLineY);

首先来画背景图片 ,和小人,这里背景图片大小不对,没想到有什么好的方法,这里先写死(求解决,求不打死)。

 Bitmap bitmap = BitmapFactory.decodeResource(getResources(), com.wingsofts.my360clean.R.drawable.mb);

        BitmapFactory.Options opt = new BitmapFactory.Options();
        opt.inJustDecodeBounds = true;

//        BitmapFactory.decodeResource(getResources(), com.wingsofts.my360clean.R.drawable.t,opt);
//        int bgWidth = opt.outWidth;
//        int bgHeight = opt.outHeight;

        //按线的长度缩放背景图
//        Log.e("wing",bgWidth + " " +scale+"");
        opt.inSampleSize= 2;
//        opt.outWidth = 500;
        opt.inJustDecodeBounds = false;
        Bitmap background =BitmapFactory.decodeResource(getResources(), com.wingsofts.my360clean.R.drawable.t,opt);

        Paint p = new Paint();
        p.setStyle(Paint.Style.STROKE);
        p.setStrokeWidth(20);
        Path path = new Path();

        //坐标写死微调。。。别打我
        canvas.drawBitmap(background,100,mLineY - background.getHeight()+100,p);

        Point endPoint = new Point(600, mLineY);

然后画两个圈圈。

        p.setColor(Color.GRAY);
        canvas.drawCircle(100, endPoint.y, 10, p);
        canvas.drawCircle(endPoint.x,endPoint.y,10,p);

之后根据一个标记位 isDrawBack来判断是否画线反弹。这里默认是不反弹。

            p.setColor(Color.YELLOW);
            path.moveTo(100, mLineY);
            path.quadTo(supPoint.x, supPoint.y, endPoint.x, endPoint.y);//绘制贝塞尔曲线,
            canvas.drawPath(path, p);
            canvas.drawPoint(supPoint.x, supPoint.y, p);

            mBitmapX = supPoint.x - bitmap.getWidth() / 2;
            mBitmapY = (supPoint.y -mLineY)/2 + mLineY- bitmap.getHeight();
            canvas.drawBitmap(bitmap, mBitmapX, mBitmapY, p);

注意上面bitmap的坐标计算,这里为了方便,贝塞尔曲线只画中点的。#实际上是不会# 观察辅助点坐标

猜测辅助点到切线点  和切线点到mLineY的距离相等,然后计算出bitmap所在的坐标,进行绘制。

然后来绘制下拉时候的样子,重写onTouchEvent,主要是改变辅助点坐标和bitmap坐标,在action_move改变坐标 最后通知重绘。重写action_up来改变最重点的坐标, 改变isDrawBack标记位,通知阶段为上弹阶段。

知识补充:getX是相对view的坐标  getRawX是相对屏幕的坐标.

 @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:

                supPoint.x = (int) event.getX();
                if(event.getY()>mLineY)
                supPoint.y = (int) event.getY();

                invalidate();
                break;
            case MotionEvent.ACTION_UP:

                endX = (int) event.getX();
                endY = (int) event.getY();

                isDrawBack = true;
                invalidate();
                break;
        }
        return true;
    }

最后来绘制回弹的效果,相信看过之前我的文章的都知道我采用一种percent办法。这里给一个参数mFlyPercent,从100开始递减,递减辅助点的y坐标和bitmap的y坐标,来实现动画效果。 如果mFlyPercent<0 则代表绘制完毕  重置标志位和百分比。

if (isDrawBack) {

            p.setColor(Color.YELLOW);
            path.moveTo(100, mLineY);
            path.quadTo(supPoint.x, mLineY + (supPoint.y - mLineY) * mFlyPercent / 100, endPoint.x, endPoint.y);
            canvas.drawPath(path, p);

            if(mFlyPercent >0) {
                canvas.drawBitmap(bitmap, mBitmapX, mBitmapY * mFlyPercent/100, p);
                mFlyPercent -=5;
                postInvalidateDelayed(10);
            }else {

                mFlyPercent = 100;
                isDrawBack = false;
            }

这样,变结束了模仿360内存清理效果,对于x坐标的计算。。。日后再研究。

本项目地址:点击打开链接

时间: 2024-11-09 22:26:10

wing带你玩转自定义view系列(1) 仿360内存清理效果的相关文章

wing带你玩转自定义view系列(2) 简单模仿qq未读消息去除效果

上一篇介绍了贝塞尔曲线的简单应用 仿360内存清理效果 这一篇带来一个  两条贝塞尔曲线的应用 : 仿qq未读消息去除效果. 转载请注明出处:http://blog.csdn.net/wingichoy/article/details/50503630 老规矩,先上效果图: qq的未读消息去除很炫酷,其实就是用了两条贝塞尔曲线,我们按思路来,先来画两个圆,及两条贝塞尔曲线,辅助点为圆心y坐标的一半.我们把下面移动的圆,叫做mMoveCircle. 这样一画,就很简单明了了对不对.只要在拖动的时候

自定义View系列教程05--示例分析

自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onLayout源码详尽分析 自定义View系列教程04–Draw源码分析及其实践 自定义View系列教程05–示例分析 PS:如果觉得文章太长,那就直接看视频吧 之前结合源码分析完了自定义View的三个阶段:measure,layout,draw. 那么,自定义有哪几种常见的方式呢? 直接继承自View 在使用该方式实现自定义View时通常的核心操作都在onDraw

自定义View系列教程01--常用工具介绍

在自定义View的时候,常常会用到一些Android系统提供的工具.这些工具封装了我们经常会用到的方法,比如拖拽View,计算滑动速度,View的滚动,手势处理等等.如果我们自己去实现这些方法会比较繁琐,而且容易出一些bug.所以,作为自定义View系列教程的开端,先介绍一下这些常用的工具,以便在后续的学习和工作中使用. Configuration ViewConfiguration GestureDetector VelocityTracker Scroller ViewDragHelper

自定义View系列教程07--详解ViewGroup分发Touch事件

自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程03–onLayout源码详尽分析 自定义View系列教程04–Draw源码分析及其实践 自定义View系列教程05–示例分析 自定义View系列教程06–详解View的Touch事件处理 自定义View系列教程07–详解ViewGroup分发Touch事件 PS:如果觉得文章太长,那就直接看视频吧 在上一篇中已经分析完了View对于Touch事件的处理,在此基础上分析和理

自定义View系列教程04--Draw源码分析及其实践

通过之前的详细分析,我们知道:在measure中测量了View的大小,在layout阶段确定了View的位置. 完成这两步之后就进入到了我们相对熟悉的draw阶段,在该阶段真正地开始对视图进行绘制. 按照之前的惯例,我们来瞅瞅View中draw( )的源码 public void draw(Canvas canvas) { final int privateFlags = mPrivateFlags; final boolean dirtyOpaque = (privateFlags & PFL

带你玩转java多线程系列 “道篇” 多线程的优势及利用util.concurrent包测试单核多核下多线程的效率

java多线程 “道篇” - 多线程的优势及用concurrent包测试单核多核下多线程的效率 1 超哥对于多线程自己的理解 2 测试代码 3 CountDownLatch这个同步辅助类科普 4 如何把电脑设置成单核 5 测试结果 1 超哥对于多线程自己的理解 超哥的理解:对于多线程,无非是对于顺序执行下任务的一种抽取和封装,将原来顺序执行的任务单独拿出来放到线程类的run方法中,通过线程类的start方法进行执行,对于多线程访问共同资源时,我们需要加锁,也就是只有某个线程在拥有锁的时候,才能够

自定义View系列教程02--onMeasure源码详尽分析

PS:如果觉得文章太长,那就直接看视频吧 大家知道,自定义View有三个重要的步骤:measure,layout,draw.而measure处于该链条的首端,占据着极其重要的地位:然而对于measure的理解却不是那么容易,许多问题都是一知半解,比如:为什么父View影响到了子View的MeasureSpec的生成?为什么我们自定义一个View在布局时将其宽或者高指定为wrap_content但是其实际是match_parent的效果?子View的specMode和specSize的生成依据又是

转载爱哥自定义View系列--Paint详解

上图是paint中的各种set方法 这些属性大多我们都可以见名知意,很好理解,即便如此,哥还是带大家过一遍逐个剖析其用法,其中会不定穿插各种绘图类比如Canvas.Xfermode.ColorFilter等等的用法. set(Paint src) 顾名思义为当前画笔设置一个画笔,说白了就是把另一个画笔的属性设置Copy给我们的画笔,不累赘了 setARGB(int a, int r, int g, int b) 不扯了,别跟我说不懂 setAlpha(int a) 同上 setAntiAlias

转载爱哥自定义View系列--文字详解

FontMetrics FontMetrics意为字体测量,这么一说大家是不是瞬间感受到了这玩意的重要性?那这东西有什么用呢?我们通过源码追踪进去可以看到FontMetrics其实是Paint的一个内部类,而它里面呢就定义了top,ascent,descent,bottom,leading五个成员变量其他什么也没有: 这五个成员变量除了top和bottom我们较熟悉外其余三个都很陌生是做什么用的呢?首先我给大家看张图: 这张图很简单但是也很扼要的说明了top,ascent,descent,bot