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