Android ListView+ScrollView显示和触摸冲突解决
2015-11-23 15:38
555 查看
最近在项目中碰到ListView+ScrollView这个需求,发现会产生两个冲突:
1.在ScrollView中ListView显示不全的冲突2.ScrollView和ListView触摸事件的冲突
正文:
网上查了很多资料,发现冲突1原来是ScrollView中的ListView无法计算的高度导致的,解决这个冲突的方法之一是只要调用list条目的measure方法,重新计算高度即可。public static void setListViewHeightBasedOnChildren(ListView listView,boolean isLast) { if (listView == null) return; ListAdapter listAdapter = listView.getAdapter(); if (listAdapter == null) return; int totalHeight = 0; for (int i = 0; i < listAdapter.getCount(); i++) { View listItem = listAdapter.getView(i, null, listView);//条目对象 listItem.measure(0, 0);//重绘 //计算条目总高度 totalHeight += listItem.getMeasuredHeight(); } ViewGroup.LayoutParams params = listView.getLayoutParams(); if(isLast){ //因为我的项目底部还有个菜单栏,判断是最后一个listview就加上底部的高度,没有的话可以不加 params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1))+dip2px(50); }else{ params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); } //重新设置listView的高度 listView.setLayoutParams(params); }
经过这样,ListView就能正常显示了,但是还有一个冲突时触摸事件的问题。有几种情况:
1.内部ListView不需要点击事件
2.ListView需要点击事件
第一种情况比较好解决,直接让ScrollView拦截所有触摸事件即可。在自定义ScrollView中,在里面重写onInterceptTouchEvent(MotionEvent ev)方法
public boolean onInterceptTouchEvent(MotionEvent ev) { float x = 0; float y = 0; switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: x = ev.getX(); y = ev.getY(); break; case MotionEvent.ACTION_MOVE: float currX = ev.getX(); float currY = ev.getY(); float dx = Math.abs(currX-x); float dy = Math.abs(currY-y); x = currX; y = currY; if(dx>dy){ //水平移动不拦截 return false; } } return true; }
第二种情况需要重写ListView的dispatchTouchEvent(MotionEvent ev)方法
float x = 0; float y = 0; switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: x = ev.getX(); y = ev.getY(); break; case MotionEvent.ACTION_MOVE: float currX = ev.getX(); float currY = ev.getY(); float dx = Math.abs(currX - x); float dy = Math.abs(currY - y); x = currX; y = currY; if (dx <= 5 && dy <= 5) { //小范围移动或点击也由父类分发事件 return super.dispatchTouchEvent(ev); } else if (dx > dy) { //水平移动由父类分发事件 return super.dispatchTouchEvent(ev); } else { //listview不处理事件 return false; } } return super.dispatchTouchEvent(ev);
至此,ListView和ScrollView两个冲突都被解决完成。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories