ParallaxHeaderViewPager项目头部控件如果设置了事件,HeaderFameLayout.dispatchTouchEvent方法就会返回true,OuterFameLayout.dispatchTouchEvent方法就不会继续分配事件,导致viewpager接收不到事件,listview就不能滚动。
如果想在设置了点击事件的控件上滑动时,viewpager也能接收事件,需从下面几个点出发:
1、HeaderFameLayout.dispatchTouchEvent返回true时,OuterFameLayout.dispatchTouchEvent方法中手动调用viewpager.dispatchTouchEvent方法。
2、滚动的时候不触发HeaderFameLayout中的click事件,HeaderFameLayout.dispatchTouchEvent中需要判断,如果是滚动就直接返回,并取消之前的down,move事件。
3、HeaderViewPager.dispatchTouchEvent中需要对异常进行捕捉
具体代码:
布局文件
<?xml version="1.0" encoding="utf-8"?>
<com.astuetz.OuterFameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/outer"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.astuetz.HeaderViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.astuetz.HeaderFameLayout
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="@dimen/header_height" >
<com.flavienlaurent.notboringactionbar.KenBurnsSupportView
android:id="@+id/header_picture"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/header_logo"
android:layout_width="@dimen/header_logo_size"
android:layout_height="@dimen/header_logo_size"
android:layout_gravity="center"
android:src="@drawable/ic_header_logo" />
<com.astuetz.PagerSlidingTabStrip
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="48dip"
android:layout_gravity="bottom"
android:background="@android:color/transparent" />
</com.astuetz.HeaderFameLayout>
</com.astuetz.OuterFameLayout>
public class HeaderFameLayout extends FrameLayout
{
public static boolean consume = false;
public HeaderFameLayout(Context context, AttributeSet attrs)
{
super(context, attrs);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev)
{
if(OuterFameLayout.isScrolled)
{
MotionEvent event = MotionEvent.obtain(ev);
event.setAction(MotionEvent.ACTION_CANCEL);
super.dispatchTouchEvent(event);
event.recycle();
return false;
}
boolean result = super.dispatchTouchEvent(ev);
consume = result;
return result;
}
}
public class OuterFameLayout extends FrameLayout
{
private ViewPager mViewPager;
private float startX, startY, curX, curY;
public static boolean isScrolled = false;
public void setViewPager(ViewPager viewPager)
{
mViewPager = viewPager;
}
public OuterFameLayout(Context context, AttributeSet attrs)
{
super(context, attrs);
}
private boolean _isFirstTime = false;
private MotionEvent _downEvent = null;
@Override
public boolean dispatchTouchEvent(MotionEvent ev)
{
switch (ev.getAction())
{
case MotionEvent.ACTION_DOWN:
startX = ev.getX();
startY = ev.getY();
curX = startX;
curY = startY;
_downEvent = MotionEvent.obtain(ev);
_isFirstTime = true;
isScrolled = false;
break;
case MotionEvent.ACTION_MOVE:
curX = ev.getX();
curY = ev.getY();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
isScrolled = false;
break;
}
float dx = Math.abs(curX - startX);
float dy = Math.abs(curY - startY);
isScrolled = dx > 10 || dy > 10;
boolean result = super.dispatchTouchEvent(ev);
if(HeaderFameLayout.consume && isScrolled && mViewPager != null)
{
//HeaderFameLayout.dispatchTouchEvent返回true并且是滚动的前提下才给viewpager分配事件
if (_isFirstTime)
{
_isFirstTime = false;
mViewPager.dispatchTouchEvent(_downEvent);//只有分配了down事件,move事件才能生效
_downEvent.recycle();
_downEvent = null;
}
else
{
MotionEvent event = MotionEvent.obtain(ev);
mViewPager.dispatchTouchEvent(event);
event.recycle();
}
}
return result;
}
}
public class HeaderViewPager extends ViewPager
{
public HeaderViewPager(Context context, AttributeSet attrs)
{
super(context, attrs);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev)
{
try
{
return super.dispatchTouchEvent(ev);
}
catch (IllegalArgumentException ex)
{
ex.printStackTrace();
}
return false;
}
}