zoukankan      html  css  js  c++  java
  • 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坐标的计算。。。日后再研究。

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


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

  • 相关阅读:
    centos7编译安装php 遇到的问题
    linux中以.d结尾的目录
    webpack 的安装与使用
    nginx 设置反向代理
    常用git命令
    windows命令行模式打开目录
    scapy 中sniff指定的数据包并打印指定信息
    python scapy中sniffer的用法以及过滤器
    scapy构造数据包
    21天实战人工智能系列:人工智能产品经理最佳实践(1)
  • 原文地址:https://www.cnblogs.com/muyuge/p/6333550.html
Copyright © 2011-2022 走看看