最近在做一个录音麦克风,长按着录制,提起结束。
我是用onTouchListener实现的,然后问题就出现了:
1.长按麦克风图标,手滑了,滑到图标外,ACTION_UP不触发,查询后发现ACTION_CANCEL在移出控件后触发,不再监听到UP。问题:如何在任何处提起手指都能实现ACTION_UP(结束录音的效果)?图标有点小,直接判断ACTION_CANCEL效果不好。
2.作死使用了ViewPager,按住图标后划动,优先给到了ViewPager进行消费,导致第二个界面还在进行录音。
有大神知道如何解决?或者给思路也可以,谢谢各位!
b.tvSpeech.setOnTouchListener((v, event) -> {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
//记录录制时长的
updateDialogTime.start();
downTime = System.currentTimeMillis();
//一个dialog录音动画
audioSpeakDialog.showAtLocation(v, Gravity.CENTER, 0, 0);
setDrawableTop(b.tvSpeech, R.drawable.voice_record_press_icon);
b.tvSpeech.setText(" 松开结束");
audioSpeakDialog.startAnim();
//开始录音
startAudio();
return true;
case MotionEvent.ACTION_UP:
//记录录制时长的
updateDialogTime.stop();
//一个dialog录音动画
audioSpeakDialog.dismiss();
setDrawableTop(b.tvSpeech, R.drawable.voice_record_icon);
b.tvSpeech.setText(" 按住说话");
audioSpeakDialog.stopAnim();
//结束录音
stopAudio();
return true;
}
return false;
});
这个让我想起很久之前做的一个rv元素拖拽脱离rv组件之外。https://images.xiaozhuanlan.com/photo/2023/f30191e9d078ed1ef852da496ffcbb93.gif,左边是rv,右边是rv之外地方。
松手后,让item还原。
按照问题的描述,按住某个位置然后监听,手指移动到目标之外正常来说事件就是cancel,这是符合正常逻辑的。上面我做的这个,和这个问题有一个共同点,就是目标被拖走了,松手逻辑一定是up。只不过问题的view不会跟着手指。
解决方案:
上面我做的效果是这样的,长按,复制一个目标view,显示在被复制的目标上面,被复制的view需要一个依赖容器,那就创建一个全屏透明的frame,让被复制的依赖,手指就可以全屏移动了,只不过移动的同时反馈的xy控制了复制后的view。监听被复制的view的touch,松手就可以拿到up。
回到这个问题,也可以同样解决,长按,复制录音view,创建透明全屏布局,把复制后view放进去。放的位置和被复制的位置一样的,甚至可以不显示也可以。这个时候,复制后的view设置touch,拿到这个touch的up,可以继续你的逻辑。
事件的传递机制是从父到子,如果子没有消费,又到父那里。按这个思路,你可以给你的空间包一个老爸,透明的就好,或者你复写你控件的容器。我看了一下微信语音的,按着就整个屏幕了。起了一个遮罩层。