天天看點

安卓解決viewPager+scrollView+listView滑動沖突的問題

很多人在開發過程中都會設計到首頁裡面的排版功能,整個頁面是一個可滑動的scrollView,上面是一個viewpager輪播圖,然後下面又有帶滑動的ListView,我們一般會先禁用ListView的滑動功能,讓整個ScrollView在首頁上下滑動就可以了。

禁用listView的滑動其實就是自定義一個View重寫裡面的onMeasure方法就行了,然後對于輪播圖和ScrollView的滑動沖突我也是通過自定義的兩個InsideViewPager和PagerScrollView來處理,後面會貼出3種自定義View的代碼。最後就是一個界面體驗的小問題,所有的可滑動的View控件,在滑動到螢幕邊緣的時候都會有一個并不是很美觀的陰影效果,這裡我們可以用相同的方式來解決:

xml檔案裡面:

<ScrollView

        android:id="@+id/scrollView" 

        android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:fadingEdge="none"

    android:overScrollMode="never"

    android:fillViewport="true">

     代碼裡面:

scrollView = getActivity().findViewById(R.id.scrollView);

       scrollView.setHorizontalFadingEdgeEnabled(false);

下面貼出解決滑動沖突的代碼:

自定義ScrollView:

package cn.wifi.youngrefersto.view;

import android.content.Context;

import android.util.AttributeSet;

import android.view.GestureDetector;

import android.view.GestureDetector.SimpleOnGestureListener;

import android.view.MotionEvent;

import android.widget.ScrollView;

public class PagerScrollView extends ScrollView{

private GestureDetector mGestureDetector;  

public PagerScrollView(Context context) {

super(context);

init();

}

public PagerScrollView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

init();

}

public PagerScrollView(Context context, AttributeSet attrs) {

super(context, attrs);

init();

}

private void init() {  

        mGestureDetector = new GestureDetector(getContext(),  

                new YScrollDetector());  

        setFadingEdgeLength(0);  

    }  

    @Override  

    public boolean onInterceptTouchEvent(MotionEvent ev) {  

        return super.onInterceptTouchEvent(ev)  

                && mGestureDetector.onTouchEvent(ev);  

    }  

    private class YScrollDetector extends SimpleOnGestureListener {  

        @Override  

        public boolean onScroll(MotionEvent e1, MotionEvent e2,  

                float distanceX, float distanceY) {  

            if (Math.abs(distanceY) >= Math.abs(distanceX)) {  

                return true;  

            }  

            return false;  

        }  

    }  

}

自定義ViewPager:

package cn.wifi.youngrefersto.view;

import android.content.Context;

import android.support.v4.view.ViewPager;

import android.util.AttributeSet;

import android.view.MotionEvent;

public class InsideViewPager extends ViewPager {

float curX = 0f;

float downX = 0f;

OnSingleTouchListener onSingleTouchListener;

public InsideViewPager(Context context) {

super(context);

}

public InsideViewPager(Context context, AttributeSet attrs) {

super(context, attrs);

}

@Override

public boolean onTouchEvent(MotionEvent ev) {

curX = ev.getX();

// TODO Auto-generated method stub

if (ev.getAction() == MotionEvent.ACTION_DOWN) {

downX = curX;

}

int curIndex = getCurrentItem();

if (curIndex == 0) {

if (downX <= curX) {

getParent().requestDisallowInterceptTouchEvent(false);

} else {

getParent().requestDisallowInterceptTouchEvent(true);

}

} else if (curIndex == getAdapter().getCount() - 1) {

if (downX >= curX) {

getParent().requestDisallowInterceptTouchEvent(false);

} else {

getParent().requestDisallowInterceptTouchEvent(true);

}

} else {

getParent().requestDisallowInterceptTouchEvent(true);

}

return super.onTouchEvent(ev);

}

public void onSingleTouch() {

if (onSingleTouchListener != null) {

onSingleTouchListener.onSingleTouch();

}

}

public interface OnSingleTouchListener {

public void onSingleTouch();

}

public void setOnSingleTouchListner(

OnSingleTouchListener onSingleTouchListener) {

this.onSingleTouchListener = onSingleTouchListener;

}

}

自定義ListView:

package cn.wifi.youngrefersto.view;

import android.content.Context;

import android.util.AttributeSet;

import android.widget.ListView;

public class NoScrollListView extends ListView{  

public NoScrollListView(Context context, AttributeSet attrs) {  

            super(context, attrs);  

    }  

    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  

    {  

        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,  

                        MeasureSpec.AT_MOST);  

        super.onMeasure(widthMeasureSpec, expandSpec);  

    }  

}  

繼續閱讀