fragment中 ScrollView 同时嵌套viewpager banner和 listview, scrollview 滑动异常·

fragment中 ScrollView                      同时嵌套viewpager banner和                  listview,

fragment中 ScrollView 同时嵌套viewpager banner和 listview, scrollview 滑动异常·

如图所示

在fragment首次加载或 onHiddenChanged事件发生后 scrollview都会滑动到listview的顶部

fragment中 ScrollView 同时嵌套viewpager banner和 listview, scrollview 滑动异常·

这破scrollview ,上一个项目也遇到同样的问题 忘了怎么解决的了,这次记录下来  首先用的listview是这样修改过的 以适应scrollview
public class CustomListView extends ListView {

    public CustomListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    public CustomListView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
                MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, expandSpec);

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        if (height != 0) {
            super.onSizeChanged(w, height, oldw, oldh);
        } else {
            super.onSizeChanged(w, h, oldw, oldh);
        }
    }

    int height = 0;

    public void setHeight(int height) {
        this.height = height;
    }

}

在 fragment onHiddenChanged 事件之后 hidden 为false fragment显示时, scrollview 会调用 onLayout 事件 然后OnScrollChangeListener 才能监听到滑动变化 ,now方法来了 

我在 fragment onHiddenChanged  hidden 为 true时记录 scrollview的 scrollY值   在scrollview的 onlayout 事件 中调用 scrollTo(0, scrollY); 来设置Y轴滑动距离,完美解决  scrollview代码如下 :


import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ScrollView;


public class MyScrollView extends ScrollView {

    private float xLast, yLast, xDistance, yDistance;

    // ScrollView的子View, 也是ScrollView的唯一一个子View
    private View contentView;

    // 用于记录正常的布局位置
    private Rect originalRect = new Rect();

    private int scrollY;

    @Override
    public void setScrollY(int scrollY) {
        this.scrollY = scrollY;
    }

    @Override
    public void setOnScrollChangeListener(OnScrollChangeListener l) {
        super.setOnScrollChangeListener(l);
    }

    public MyScrollView(Context context) {
        super(context);
    }


    public MyScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    @Override
    protected void onFinishInflate() {
        if (getChildCount() > 0) {
            contentView = getChildAt(0);
        }
    }


    @Override
    public void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);


        if (contentView == null)
            return;

        // ScrollView中的唯一子控件的位置信息, 这个位置信息在整个控件的生命周期中保持不变
        originalRect.set(contentView.getLeft(), contentView.getTop(),
                contentView.getRight(), contentView.getBottom());
        scrollTo(0, scrollY);
    }

    /**
     * 在这里解决滑动上下滑动,左右滑动冲突
     *
     * @param ev
     * @return
     */
    @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);

    }
}

fragment代码简单: 
@Override
public void onHiddenChanged(boolean hidden) {
    super.onHiddenChanged(hidden);
    if (hidden) {
        sv.setScrollY(sv.getScrollY());
    }
}