ParallaxHeaderViewPager改进

程谭三
2023-12-01

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>

HeaderFameLayout.java

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;
    }
    
}


OuterFameLayout.java

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;
    }
}


HeaderViewPager.java

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;
	}
}




 类似资料: