Android 解决BottomSheetDialog 拖曳冲突问题
问题
在实现BottomSheetDialog中嵌入Webview的时候,会向下拖动会将整个dialog消失掉而不是滑动webview内容,如下:
解决问题
1.提出设想
一般webview的向下滑动/拖动的效果应该是可以正常显现出来的,而BottomSheetDialog控件本身自带的拖动效果也是将其整个View给消失掉的,这样两者在同时向下拖动时就会产生部分冲突。(如果没有冲突,那么必定是谷歌在设计时以及做了处理。)因此,可以把问题的解决关键假定为:当发生向下动作的,去解决这之间的“冲突”。
2.源码分析
翻开BottomSheetDialog的源码,发现内容并不多:
可以看见,所有setContentView的入口都调用了这个wrapInBottomSheet方法。
private View wrapInBottomSheet(int layoutResId, View view, ViewGroup.LayoutParams params) {final FrameLayout container = (FrameLayout) View.inflate(getContext(),R.layout.design_bottom_sheet_dialog, null);final CoordinatorLayout coordinator =(CoordinatorLayout) container.findViewById(R.id.coordinator);if (layoutResId != 0 && view == null) {view = getLayoutInflater().inflate(layoutResId, coordinator, false);}FrameLayout bottomSheet = (FrameLayout) coordinator.findViewById(R.id.design_bottom_sheet);mBehavior = BottomSheetBehavior.from(bottomSheet);mBehavior.setBottomSheetCallback(mBottomSheetCallback);mBehavior.setHideable(mCancelable);if (params == null) {bottomSheet.addView(view);} else {bottomSheet.addView(view, params);}//...省略return container;}
传入的View最终会被add进一个FrameLayout的bottomSheet中,然后通过bottomSheet来实例化一个BottomSheetBehavior,之后给这个mBehavior设置了一个mBottomSheetCallback,我们来看看其内容是什么:
private BottomSheetBehavior.BottomSheetCallback mBottomSheetCallback= new BottomSheetBehavior.BottomSheetCallback() {@Overridepublic void onStateChanged(@NonNull View bottomSheet,@BottomSheetBehavior.State int newState) {if (newState == BottomSheetBehavior.STATE_HIDDEN) {cancel();}}@Overridepublic void onSlide(@NonNull View bottomSheet, float slideOffset) {}};
可以看出里面涉及到了对BottomSheet的状态监听,逻辑判断则是根据BottomSheetBehavior的状态来进行相应处理,再来看看BottomSheetBehavior中有哪些状态:
/*** The bottom sheet is dragging.*/public static final int STATE_DRAGGING = 1;/*** The bottom sheet is settling.*/public static final int STATE_SETTLING = 2;/*** The bottom sheet is expanded.*/public static final int STATE_EXPANDED = 3;/*** The bottom sheet is collapsed.*/public static final int STATE_COLLAPSED = 4;/*** The bottom sheet is hidden.*/public static final int STATE_HIDDEN = 5;
找到了STATE_DRAGGING 状态,假定我们能在BottomSheetCallback的onStateChanged的监听方法中能监听到该对应的动作,那么我们就能拦截处理一开始出现的问题。
于是,在onStateChanged中输出日志,打印各动作的newState对应的状态码是多少,最后发现,果然当向下拖动整个view时,其newState为STATE_DRAGGING。因此,只要在这里将状态改为不是该状态可能就会实现要求的效果。根据名称选择STATE_EXPANDED 来做相应的处理。
但是如何来做呢?
BottomSheetCallback是通过BottomSheetBehavior来set的,而BottomSheetBehavior则有
public static <V extends View> BottomSheetBehavior<V> from(V view)
的静态方法来实例化,于是到这里就很清晰了。
解决方案
1.改写BottomSheetCallback里的判断逻辑
private BottomSheetBehavior.BottomSheetCallback mBottomSheetCallback= new BottomSheetBehavior.BottomSheetCallback() {@Overridepublic void onStateChanged(@NonNull View bottomSheet,@BottomSheetBehavior.State int newState) {if (newState == BottomSheetBehavior.STATE_DRAGGING) {//判断为向下拖动行为时,则强制设定状态为展开bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED );}LogUtil.e(TAG, "onStateChanged——>" + newState);}@Overridepublic void onSlide(@NonNull View bottomSheet, float slideOffset) {LogUtil.e(TAG, "onSlide——>" + slideOffset);}};
2.实例化BottomSheetBehavior,给BottomSheetDialog设置回调
mBottomSheetDialog.setmBottomSheetCallback((FrameLayout)(view.getParent()));//因为view是被add进去,设置的回调监听是其parent view
public void setmBottomSheetCallback(View sheetView) {if (bottomSheetBehavior == null) {bottomSheetBehavior = BottomSheetBehavior.from(sheetView);}bottomSheetBehavior.setBottomSheetCallback(mBottomSheetCallback);}
3.方案效果
总结
以上只是简单地结合源码分析并提出猜想的一种可解决方案,还有很多问题并未深究。一开始所说的“冲突”其实是已经被谷歌解决了的,只是在依据此的基础上做了些额外的处理使其能依照其规则正常的运行。其它例如加入RecycleView等也应该是类似的解决方案,一步步分析源码和猜想尝试,总会解决。
Android 解决BottomSheetDialog 拖曳冲突问题相关推荐
- Android Studio androidx 包冲突解决方法
Android Studio androidx 包冲突解决方法 参考文章: (1)Android Studio androidx 包冲突解决方法 (2)https://www.cnblogs.com/ ...
- Eclipse上GIT插件EGIT使用手册之八_解决推送冲突
为什么80%的码农都做不了架构师?>>> 多人协作开发的情况下,往服务器推送更新时难免出现冲突,所以推送之前需要解决服务器端的最新版本和本地仓库的冲突.Pull操作就是把服务器 ...
- android 自定义view文字不齐,Android 解决TextView排版参差不齐的问题
Android 解决TextView排版参差不齐的问题 在app中,展示数据时,里面有汉字.数字.特殊字符时,由于全角.半角问题导致TextView参差不齐.在网上找了许多,半角转全角并没什么用,还有 ...
- git解决代码提交冲突
树冲突 文件名修改造成的冲突,称为树冲突. 比如,A同事把文件改名为A.C,B同事把同一个文件改名为B.C,那么B同事将这两个commit合并时,会产生冲突. 如果最终确定用B同事的文件名,那么解决办 ...
- Android解决程序切换后台被干掉,恢复状态问题
Android解决程序切换后台被干掉,恢复状态问题 参考文章: (1)Android解决程序切换后台被干掉,恢复状态问题 (2)https://www.cnblogs.com/caiwan/p/And ...
- Android 解决Android的TextView和EditText换行问题
Android 解决Android的TextView和EditText换行问题 参考文章: (1)Android 解决Android的TextView和EditText换行问题 (2)https:// ...
- Android解决NDK not configured问题
Android解决NDK not configured问题 参考文章: (1)Android解决NDK not configured问题 (2)https://www.cnblogs.com/chen ...
- Android 解决RecyclerView删除Item导致位置错乱的问题
Android 解决RecyclerView删除Item导致位置错乱的问题 参考文章: (1)Android 解决RecyclerView删除Item导致位置错乱的问题 (2)https://www. ...
- Android 解决不同进程发送KeyEvent 的问题
Android 解决不同进程发送KeyEvent 的问题 参考文章: (1)Android 解决不同进程发送KeyEvent 的问题 (2)https://www.cnblogs.com/TerryB ...
最新文章
- 【c++基础】ifstream的构造函数
- 如何使用Oracle的外部表查询警告日志文件
- mysql的主从复制优缺点_MySQL主从复制原理,超级详细的总结,看完全通了
- mysql增量脚本_mysql全量和增量备份脚本
- 《数学建模:基于R》——1.1 数据的描述性分析
- 编译OpenCV:cv2.cpp:23:33: fatal error: numpy/ndarrayobject.h: 没有那个文件或目录
- 9、两个栈实现队列(Python)
- Struts框架面试题
- 自动泊车停车位检测算法
- BA无标度网络(三):网络生成
- 人似秋鸿来有信,事如春梦了无痕
- 数值计算——线性最小二乘问题
- 易基因|ctDNA甲基化测序分析(ctDNA-WGBS)用于癌症检测和分子分型 | 精准医学
- 红帽 Red Hat Linux相关产品iso镜像下载【百度云】【更新7.2】
- 计算机视觉中low-level feature和high level feature的理解
- 部署并安装Discuz论坛(首先搭建LAMP环境Apache+MySQL+PHP)
- 硅基生命之漫谈-2:宇宙之基本法则:聚合与分解?
- 用php向新年问候,给客户的新年问候语
- python web框架简介Bottle Flask Tornado
- SQL语言——DML与DQL
热门文章
- 努力的蠢货与聪明的混子
- Android 开发学习资料
- PCI设备驱动与虚拟网卡驱动源码分析
- 蓝桥杯2021届C++B组省赛真题 杨辉三角形
- Failed to load ‘Assets/Plugins/******.dll‘ with error ‘找不到指定的模块。
- Android Studio 主题 - AppTheme
- vue实现商品详情页功能之商品选项卡
- C++/C试题的答案与评分标准
- uni-app 录音支持暂停、继续(ios、andorid)
- 基于HTML+CSS+JS的肇庆学院首页静态页面源码