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

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

如图所示

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

这破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());
    }
}

猜你喜欢

转载自blog.csdn.net/cumtqt/article/details/82180110
今日推荐