[Android自定義View]高仿FaceU / 微信長按錄像按鈕

最近在做一款類似FaceU的App,需要做短按拍照,長按錄像功能,雖然長按只需要LongClickListener就好了,但是要同時做出動畫效果。
在網(wǎng)上轉(zhuǎn)了一圈,發(fā)現(xiàn)仿微信長按錄像的不少,例如這個,但是仿FaceU的好像還沒有,所以決定自己寫一個。
先放一張效果圖:

仿FaceU錄像按鈕.gif

一、實(shí)現(xiàn)流程分析

按鈕要實(shí)現(xiàn)類似ClickListener和LongClickListener的功能,因此需要監(jiān)聽觸控事件
按照時間順序,按鈕的動畫效果大概是這樣:

  • 還沒有到達(dá)LongClick的時間閾值,沒有任何反應(yīng),靜態(tài)的畫面為中間一個半透明白色圓形,外面一個白色圓環(huán)
  • 動畫開始,中間的圓形消失,變成一個逐漸擴(kuò)大的綠色圓形
  • 在綠色圓形擴(kuò)大的同時,外面的圓環(huán)擴(kuò)大,同時進(jìn)度條開始移動
  • 綠色圓形和圓環(huán)擴(kuò)大到最大值
  • 進(jìn)度條滿,達(dá)到錄像的時間閾值或用戶手指離開(ACTION_UP)

此外,還有兩個黑色半透明的圓環(huán)作為描邊,但是效果不是很明顯,略去不表。

二、代碼實(shí)現(xiàn)

這種效果,拿自定義View來做再合適不過了,整個動畫不需要任何素材,可以直接通過重寫View的draw函數(shù)實(shí)現(xiàn)。

分配率無關(guān)的尺寸獲取

我們希望繪制出的圖形在不同屏幕上都顯示類似的效果,所以要獲取一個像素密度相關(guān)的尺寸

public int getRefLength(float len) {
    return (int) (mContext.getResources().getDisplayMetrics().density * len + 0.5F);
}

圓形/圓環(huán)的繪制

圓形/圓環(huán)的繪制比較簡單,只需要設(shè)定Paint的屬性,然后在onDraw里面交給canvas即可。如果是圓環(huán),那么類型就是Style.STROKE,實(shí)心圓是Style.FILL_AND_STROKE

centerCirclePaint = new Paint();
centerCirclePaint.setColor(colorWhiteP60);
centerCirclePaint.setAntiAlias(true);
centerCirclePaint.setStyle(Style.FILL_AND_STROKE);

canvas.drawCircle(centerX, centerY, innerCircleRadiusToDraw, centerCirclePaint);

圓弧的繪制

圓弧的繪制比較類似,但是調(diào)用的是不同的函數(shù),給定的是圓弧的包圍矩形,另外我們希望進(jìn)度條從最上面開始,所以我們的起始角度是270度(0度是右邊)

canvas.drawArc(outMostCircleRect, startAngle270, 360.0F, false, outMostWhiteCirclePaint);

LongClick狀態(tài)判斷

如何判斷用戶是單擊還是長按呢?
我們可以監(jiān)聽用戶的觸摸事件,設(shè)定一個超時的閾值,如果用戶按下超過這個時間,那么就是長按,否則就是單擊。
超時判斷可以采用一個定時的消息,或者每隔一小段時間檢查一下。

public boolean onTouchEvent(MotionEvent e) {
    switch (e.getAction()) {
        case MotionEvent.ACTION_DOWN:
            Log.d(TAG, "onTouchEvent: down");
            startTicking();
            break;
        case MotionEvent.ACTION_MOVE:
            Log.d(TAG, "onTouchEvent: move");
            break;
        case MotionEvent.ACTION_UP:
            Log.d(TAG, "onTouchEvent: up");
            reset();
            break;

    }
    return true;
}

動畫時限

中間圓形的縮放時間和錄制時間是不一樣的,我們要分開處理進(jìn)度條的動畫和中間圓形按鈕的動畫。
可以考慮設(shè)定一個比例10%,表示如果錄制視頻的時限為5秒,那么圓形在0.5秒時縮放到最大。

事件回調(diào)

在獲取到點(diǎn)擊和長按的動作并且顯示對應(yīng)的動畫以后,我們需要將這個消息傳出去。
設(shè)定一個這樣的監(jiān)聽器:

public interface ClickListener {
    void onClick();
    void onLongClickStart();
    void onLongClickEnd();
}
  • 當(dāng)用戶ACTION_DOWN沒有超過閾值時,onClick被調(diào)用
  • 當(dāng)用戶ACTION_DOWN剛好超過閾值時,onLongClickStart被調(diào)用
  • 當(dāng)用戶ACTION_DOWN超過閾值后離開或者錄制時間達(dá)到限制時onLongClickEnd被調(diào)用

三、為不同配色的App定制

根據(jù)前面的分析,我們的按鈕主色調(diào)是綠色,如果應(yīng)用在其他App中,只需要改主色調(diào),其他不變即可。
改成橙色試試?


FaceU_orange.gif

最后給出Demo示例代碼(RecordButton)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,048評論 25 709
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,334評論 4 61
  • 內(nèi)容抽屜菜單ListViewWebViewSwitchButton按鈕點(diǎn)贊按鈕進(jìn)度條TabLayout圖標(biāo)下拉刷新...
    皇小弟閱讀 47,161評論 22 665
  • 第三題:什么叫做三殊圣?行持善法為何要以三殊圣攝持?你今后能否做得到? 三殊圣就是在行持善法中所具備的發(fā)心,無論在...
    緣孟閱讀 1,735評論 0 0
  • 本來早醒在床上,腦袋中突然有一個靈感,每隔一段時間寫個小總結(jié),碎碎念些瑣事,想到那些到哪,應(yīng)該很有意義,并且很有趣...
    核桃花生閱讀 358評論 0 0

友情鏈接更多精彩內(nèi)容