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咨询.
    
复制代码
相关文章
相关标签/搜索