模仿微信下拉眼睛view

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



發現了愛神的自定義view系列,我只想說一個字:凸(艸皿艸 ) !!相見恨晚啊,早看到就不會走這么多彎路了


另外相比之下我這完全是小兒科。。所以不說了,這篇是本系列完結篇....我要從零開始跟隨愛哥腳步去學自定義view了:愛哥自定義view專題


然后要說的就是  之前的博客都犯了很嚴重的錯誤,那就是不要在onDraw里new東西,不要在onDraw里new東西,不要在onDraw里new東西。重要的話說三遍。


上一篇介紹了 qq未讀消息提醒去除效果的簡化實現,不知道小伙伴們掌握的怎么樣了。


轉載請注明出處:http://write.blog.csdn.net/postedit/50503858


今天帶給大家一個很熟悉的東西,當當當當,就是微信下拉眼睛的實現了。 先看效果圖:




自評相似度  80%  哈哈=  = 。


用我們一貫的方法來剖析這個view。

首先 從內到外:

1.內部其實是兩段弧,只不過在改變畫筆的寬度。

2.中間是個圓,一直在改變透明度。

3.最外面是兩條貝塞爾曲線(重點加難點)。


首先來畫靜態的眼睛。按照順序,相信你已經輕車熟路:

mPaint.setStrokeWidth(10);
            canvas.drawArc(mRectF, 180, 10, false, mPaint);
            canvas.drawArc(mRectF, 205, 25, false, mPaint);

            //畫圓圈
            mPaint.setStrokeWidth(2);
            canvas.drawCircle(225, 225, 40, mPaint);
            canvas.drawPath(mPath, mPaint);

這樣就畫出了眼珠的靜態部分,然后根據我們的percent大法,分三個階段:1.弧變粗  2.圓圈透明度改變  3.貝塞爾區限 起點,終點,輔助點改變


那么將這三個階段用同一個percent來控制  0-33為1階段  33-66為2階段 66-100為3階段:


意外收獲:當setStrokeWidth 為0時,實際上不是0.

if(mPercent<33) {//如果為1階段,改變畫筆的大小

            float stroke = mPercent/3f;    //用0-33 來控制0-10的變化 計算的方法
            Log.e("wing","st" + stroke);
            if(stroke == 0.0){   //如果為0  則不繪制,這里用背景色解決
                mPaint.setColor(Color.BLACK);
            }else {
                mPaint.setColor(Color.GRAY);
            }
            mPaint.setStrokeWidth(stroke);
            canvas.drawArc(mRectF, 180, 10, false, mPaint);


            canvas.drawArc(mRectF, 205, 25, false, mPaint);
        }else if(mPercent < 66) {     //如果為2階段  則畫靜態的1階段

            //畫內部
            mPaint.setStrokeWidth(10);
            canvas.drawArc(mRectF, 180, 10, false, mPaint);
            canvas.drawArc(mRectF, 205, 25, false, mPaint);

            //畫圓圈
            mPaint.setStrokeWidth(2);
            int alpha = (int) ((mPercent - 33f) / 33f * 255);//根據百分比去動態控制透明度的值、

            mPaint.setAlpha(alpha);
            canvas.drawCircle(225, 225, 40, mPaint);

        }else


以上都沒什么好說的,現在來說最難的第三階段(搞了我好久)


第三階段全局用一個percent參數,由 66-100演變來的

float percent = (mPercent-66)*3f/100;


然后觀察曲線的動態變化,是從頂點開始像兩側繪制、這時候很容易想到 根據百分比動態改變起點,終點的值,代碼如下:

float mStartX = 225 -(225-115)*percent;
            float mEndX = 225+ (335-225)*percent;

            mTopPath.moveTo(mStartX ,175+(225-175)*percent);
//            Log.e("wing","start:"+(225 -(225-145)*percent) + " y:"+125+(225-125)*percent);
            mTopPath.quadTo(225, 175, mEndX, 175+(225-175)*percent );

            canvas.drawPath(mTopPath, mPaint);
然后你會驚奇的發現如下效果:

這是因為只改變了起終點,并沒有改變輔助點的Y軸。那么輔助點到底應該怎么去改變呢,來看一張圖:


根據之前在  模仿360內存清理效果的研究里發現,  在輔助點x為線段一半的情況下, 弧的切點y軸也為輔助點y的一半。 所以得出 輔助點的Y變化應為:

175-50*percent

然后來改寫貝塞爾曲線繪制代碼:

float mStartX = 225 -(225-115)*percent;//貝塞爾區限的開始x坐標
            float mEndX = 225+ (335-225)*percent;//貝塞爾區限的結束x坐標

            mTopPath.moveTo(mStartX ,175+(225-175)*percent);
//            Log.e("wing","start:"+(225 -(225-145)*percent) + " y:"+125+(225-125)*percent);
            mTopPath.quadTo(225, 175-50*percent, mEndX, 175+(225-175)*percent );//輔助點的Y坐標動態改變

            canvas.drawPath(mTopPath, mPaint);
            mTopPath.reset();
//
//            //畫靜態下邊線
////            mPath.moveTo(145, 225);
////            mPath.quadTo(225, 325, 305, 225);
////            canvas.drawPath(mPath, mPaint);
//
            mPath.moveTo(mStartX ,275-(275-225)*percent);
            mPath.quadTo(225,  275+50*percent, mEndX , 275-(275-225)*percent );
            canvas.drawPath(mPath,mPaint);

            mPath.reset();


最后 給他一個setPercent方法:

public void setPercent(int percent){
        mPercent = percent;
        invalidate();
    }


然后在MainActivity內 用seekbar動態改變他的percent值 即可達到我們想要的效果。


本篇難度較大,請讀者動手認真練習,文中坐標可根據個人喜好改變。


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

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

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