滑动冲突在android是非常常见的事情,比如ViewPager与SlidingMenu滑动,ScrollView与GridView滑动冲突。遇到这类问题最常见的解决方案就是控件自定义,自定义外层滑动控件或者自定义内层滑动控件都能较好的解决滑动问题。
我今天将我在做项目中遇到的问题和大家分享一下,我在用ScrollView嵌套普通的布局完全没有任何问题,但是将ListView丢进去bug就出来了,ListView只显示一个item的数据,然后就自定义了ListView放进去数据果然能够全部展示了,ok,这只是第一个坑,第二个坑马上就过来了,我的布局中有Banner广告图,广告图上还有搜索框,项目要求ScrollView滑动让搜索框背景色渐变,安卓原生的ScrollView也有滑动监听,但是到android M系统就不行了,低于6.0的系统完全做不到,所以我就想到自定义ScrollView,下面我将两个自定义控件的核心代码贴出来供大家参考。
自定义LIstView的代码部分:
public class ListViewForScrollView extends ListView {
public ListViewForScrollView(Context context) {
super(context);
}
public ListViewForScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ListViewForScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
*重写该方法,达到使ListView适应ScrollView的效果
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
自定义ScrollView的部分代码:
public class ObservableScrollView extends ScrollView {
private OnScrollChangedListener onScrollChangedListener = null;
public ObservableScrollView(Context context) {
super(context);
}
public ObservableScrollView(Context context, AttributeSet attrs,int defStyle) {
super(context, attrs, defStyle);
}
public ObservableScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setOnScrollChangedListener(OnScrollChangedListener onScrollChangedListener) {
this.onScrollChangedListener = onScrollChangedListener;
}
@Override
protected void onScrollChanged(int x, int y, int oldx, int oldy) {
super.onScrollChanged(x, y, oldx, oldy);
if (onScrollChangedListener != null) {
onScrollChangedListener.onScrollChanged(this, x, y, oldx, oldy);
}
}
public interface OnScrollChangedListener {
void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy);
}
}
但是有个问题紧接着就暴露出来了,自定义的ListView往往默认抢先获得焦点这就导致了已进入一定页面自定义ListView的部分获得焦点得到展示,它上面的控件就被顶了上去,经过我反复研究重写下面这个方法就能够让ScrollView默认获取焦点让二者得到很好地适应。
@Override
protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) {
return 0;
}
最近项目比较忙博客停更了一段时间,大家有什么问题或者在使用过程中遇到问题可以给我在下面留言,我会帮大家解决。