微信發(fā)送語音自定義view中的事件分發(fā)

這里通過一個(gè)自定義view的例子來看事件分發(fā)在自定義view中的使用,其實(shí)大部分的Android框架下的事件分發(fā)的也都差不多的樣子,拋磚引玉,我自己做一個(gè)記錄,如果能幫到有需要的人那就更上一層樓。
先來看一個(gè)微信發(fā)送語音的效果圖:


關(guān)于事件分發(fā)我們其實(shí)耳熟能詳,可以通過一段非常有名的偽代碼來大致了解:

  @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        boolean consume = false;
        if(onInterceptTouchEvent(ev)){
            consume = onTouchEvent(ev);
        }else {
            consume = child.dispatchTouchEvent(ev);
        }
        return consume;
 
    }

事件都是從一個(gè)DOWN開始,中間經(jīng)過一堆MOVE,到一個(gè)UP結(jié)束(先拋開CANCEL的情況)。
事件流向畫了半天,感覺也沒有人家畫的好,可以參考 這里 ,很清晰,忘記了的或者細(xì)節(jié)不清楚模糊了的可以移步去復(fù)習(xí)一下。
我們的需求是點(diǎn)擊發(fā)送按鈕后顯示浮層view,相當(dāng)于事件先由發(fā)送按鈕處理,等浮層view顯示后再交由浮層view處理,這個(gè)事件的流向很清晰,那應(yīng)該怎么做呢。
那最簡單的view的層級結(jié)構(gòu)就是發(fā)送按鈕浮層view處在同一層級,那一個(gè)問題,事件能否在parent什么都不做的情況下實(shí)現(xiàn)事件在同級別view之間的轉(zhuǎn)移呢?
肯定是不可以或者說沒有必要的,最好的方式還是通過parent來做分發(fā),由parent的決定此時(shí)到底是需要把事件交給發(fā)送按鈕還是浮層view
所以層級結(jié)構(gòu)上:

<?xml version="1.0" encoding="utf-8"?>
<!-- parent, 來控制事件的分發(fā) -->
<com.yocn.af.view.widget.WeChatParentViewGroup 
    android:id="@+id/wechat_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/ll_option"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true">

         <!-- 發(fā)送按鈕view -->
        <com.yocn.af.view.widget.WeChatVoiceTextView  
            android:id="@+id/tv_voice"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="按住 說話"/>
    </LinearLayout>
     <!-- 點(diǎn)擊后需要顯示的浮層view -->
    <com.yocn.af.view.widget.WeChatVoiceView 
        android:id="@+id/voice_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/half"
        android:visibility="gone" />

</com.yocn.af.view.widget.WeChatParentViewGroup>

我們梳理一下思路,需要做的就是:

  1. 什么都沒做時(shí)ParentViewGrouponInterceptTouchEvent要返回false,使得事件能順利的從ParentViewGroup傳遞到VoiceTextView(發(fā)送按鈕)
  2. 點(diǎn)擊到VoiceTextView(發(fā)送按鈕)時(shí),發(fā)送按鈕的dispatchTouchEvent返回true,處理DOWN事件并告訴parent需要顯示WeChatVoiceView(浮層view)
  3. parent接收到需要顯示浮層view的命令,顯示浮層view并且onInterceptTouchEvent返回true,表示事件我parent來處理,這時(shí)VoiceTextView(發(fā)送按鈕)會(huì)收到一個(gè)CANCEL事件并且不會(huì)繼續(xù)接受MOVE事件。
  4. parent來分發(fā)事件,在WeChatVoiceView(浮層view)顯示出來之后直接將后續(xù)的MOVE事件交給WeChatVoiceView(浮層view)處理,當(dāng)然浮層view的onInterceptTouchEvent需要返回true,會(huì)回調(diào)到浮層view的onTouchEvent,直接做對應(yīng)的動(dòng)畫或者手勢操作。
  5. 當(dāng)然不要忘記在parent收到ACTION_UP的時(shí)候?qū)?code>浮層view置為不可見,因?yàn)槭录怯蓀arent分發(fā)給浮層view的,當(dāng)然parent可以一直拿到事件。

至此,整個(gè)事件分發(fā)的流程就結(jié)束了。
附上代碼地址WeChatSendVoice

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

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