Android自定義view系列 - 仿360內存清理效果

jopen 8年前發布 | 14K 次閱讀 Android開發 移動開發

宗旨都是一樣,帶大家一起來研究自定義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坐標的計算。。。日后再研究。

本項目地址:點擊打開鏈接

來自: http://blog.csdn.net/wingichoy/article/details/50500479

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!