android 彈幕框架DanmakuFlameMaster,解決 控制Ui和彈幕點擊的問題.

android 直播彈幕,在使用以前,若是有人對DanmakuFlameMaster還不瞭解怎麼用的話,能夠參考郭霖的這個博客郭霖的彈幕功能實現的博客.
可是在這裏我仍是建議你們直接看DanmakuFlameMaster的官方Demo,由於版本的迭代,而上面這篇博客某些地方Api已通過時.java

  • 下面藉助郭大神博客的一張圖:
    image
  • 在這樣圖中咱們能夠看到VoideView在最底層 -> 彈幕VIew -操做View
  • VoideView :只有播放視頻的api,毫無交互操做
  • 彈幕View : 顯示彈幕view, 彈幕有可能須要點擊效果
  • 操做View : 雙擊:播放/暫停 , 單點:顯示/隱藏 整個操做的VIew , 左上滑 +亮度 , 左滑 +聲音.
    那麼問題來了,彈幕須要點擊,那麼就會攔截按下, 操做View也須要點擊和雙擊,也會攔截按下.

下面就是解決這個問題的方法: 思路:既然兩個都須要攔截點擊事件,那麼就直接讓兩個View的setOnTouchListener合併成一個setOnTouchListener,可是這裏有兩個問題:android

  • 合併到誰: 合併到DanmakuFlameMaster庫的DanmakuView
  • DanmakuFlameMaster是用implementation'com.github.ctiao:DanmakuFlameMaster:0.9.25'依賴的,怎麼樣來解決框架內部的setOnTouchListener事件呢? 答案:反射.
/* master.flame.danmaku.ui.widget.DanmakuView 的源碼,能夠看到使用自定義TouchHelper,源碼裏面直接攔截了 */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        boolean isEventConsumed = mTouchHelper.onTouchEvent(event);
        if (!isEventConsumed) {
            return super.onTouchEvent(event);
        }
        return isEventConsumed;
    }
    /*master.flame.danmaku.ui.widget.DanmakuTouchHelper,能夠看到源碼裏面onDown方法只要設置OnDanmakuClickListener ,那麼就返回true,這樣是有問題的,無論是把DanmakuView覆蓋在VoideControlBox上,仍是在VoideControlBox 下都被令另一個View 的事件出問題.*/
    private final android.view.GestureDetector.OnGestureListener mOnGestureListener = new GestureDetector.SimpleOnGestureListener() {
     @Override
     public boolean onDown(MotionEvent event) {
         if (danmakuView != null) {
             IDanmakuView.OnDanmakuClickListener onDanmakuClickListener = danmakuView.getOnDanmakuClickListener();
             if (onDanmakuClickListener != null) {
                 mXOff = danmakuView.getXOff();
                 mYOff = danmakuView.getYOff();
                 return true;
             }
         }
         return false;
     }
     //....省略了部分代碼
    };
    
    /** 解決辦法,反射獲取mTouchHelper,模擬onTouchEvent(); 而後把本身的VoideControlBox的一些事件也交給setOnTouchListener來處理,下面請看代碼 */
    DanmakuTouchHelper mTouchHelper;
    try {
        Field field = mPlayDanmakuView.getClass().getDeclaredField("mTouchHelper");
        field.setAccessible(true);
        Object obj = field.get(mPlayDanmakuView);
        if (obj instanceof DanmakuTouchHelper) {
            mTouchHelper = (DanmakuTouchHelper) obj;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    //mPlayDanmakuView 這是彈幕View 的對象.
    mPlayDanmakuView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            //ControlBox 的事件處理返回
            boolean isEvent = mPlayerHelper.mGestureDetector.onTouchEvent(event);
            boolean isEventConsumed = false;
            // 若是反射拿到了mTouchHelper ,執行onTouchEvent方法.
            if (mTouchHelper != null) {
                isEventConsumed = mTouchHelper.onTouchEvent(event);
            }
            //若是是ControlBox返回爲true 或者是彈幕事件返回爲true, 消費該事件
            if (isEvent || isEventConsumed) {
                return true;
            }
            // 處理手勢結束, 取消一些如音量View,亮度View
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_UP:
                    mPlayerHelper.endGesture();
                    break;
            }
            return true;
        }
    });
    
    
    - 好了,若是有朋友沒懂的能夠加我QQ 97149859諮詢.
    
複製代碼
相關文章
相關標籤/搜索