在网上找了一下关于ListView和ViewPager滑动冲突的问题发很多但都没有解决,也没有可运行的Demo运行。其中就包括http://www.apkbus.com/forum.phpmod=viewthread&tid=115131
于是在网上找了一下事件的分发和拦截来学习。有兴趣的同学可以看看。写的比较详细
http://www.cnblogs.com/sunzn/archive/2013/05/10/3064129.html
下面来贴一下我的代码,如果有需要的可以下载看看运行效果,当然代码我会全部贴出来。
首先来看一下布局文件。很简单就是一个listview的头部放入一个viewpager ,viewpager里面有三个图片。
下面是ListView里面的布局文件。
-
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<cn.zhongyun.listviewandviewpager.customview.MyListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
</RelativeLayout>
接下来是ViewPager的布局文件
需要注意的是ViewPager的高度要固定否则在ListView的头部会显示不出来。如果不固定的话,就要在代码里估量头部的大小然后再得到高度
-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="150dp" />
</LinearLayout>
下面来贴一下核心代码,也就是重写ListView的拦截事件处理
-
public class MyListView extends ListView {
// 滑动距离及坐标
private float xDistance, yDistance, xLast, yLast;
public MyListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public MyListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyListView(Context context) {
super(context);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
xDistance = yDistance = 0f;
xLast = ev.getX();
yLast = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
final float curX = ev.getX();
final float curY = ev.getY();
xDistance += Math.abs(curX - xLast);
yDistance += Math.abs(curY - yLast);
xLast = curX;
yLast = curY;
if (xDistance > yDistance) {
return false; //表示向下传递事件
}
}
return super.onInterceptTouchEvent(ev);
}
}
在onInterceptTouchEvent这个方法里拦截。如果在x轴上的距离大于y轴上的距离表示是ViewPager的滑动,所以滑动处理交给ViewPager的OnTouchEvent来处理,ListView不处理。(代码里返回return false)
反之 return super.onInterceptTouchEvent(ev); 表示交给当前view(也就是ListView的触摸事件处理)。当然如果你不理解可以看看上面我发的那个链接可以看看。这样就解决了滑动冲突的问题。