针对ScrollView监听事件
在Android的M(包含 api23)版本之后对外开放了监听
setOnScrollChangeListener
scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
@Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
Log.d(TAG, "onScrollChange-scrollX:" + scrollX + " scrollY:" + scrollY + " oldScrollX:" + oldScrollX + " oldScrollY:" + oldScrollY);
}
});
对于在api23之前的版本其实内部有监听不过没有开放(protected),只需要重写scrollView曝漏出即可
public class MyScrollView extends ScrollView {
/**
* 滑动回调监听
*/
private MyScrollViewListener listener;
/**
* 曝漏出
* @param listener
*/
public void setListener(MyScrollViewListener listener) {
this.listener = listener;
}
public MyScrollView(Context context) {
this(context,null);
}
public MyScrollView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public MyScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onScrollChanged(int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
super.onScrollChanged(scrollX, scrollY, oldScrollX, oldScrollY);
if (listener!=null){
listener.onScrollChanged(this,scrollX,scrollY,oldScrollX,oldScrollY);
}
}
/**
* 对外开放滑动回调类
*/
public interface MyScrollViewListener{
void onScrollChanged(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY);
}
}
其中回调参数scrollY:滑出ScrollView的距离outH
scrollView.getHeight(): scrollView可以看到的高度seeH
则在scrollView滑动过程中在监听中时时算出滑动的view距离底部的距离:
bottomH=滑动view总高度-(outH + seeH)
如果RecycleView嵌套在ScrollView中,则RecyclerView滑动距离底部距离
itemH * itemCount -(outH + seeH)
当然这个值一般在recyclerView.addOnScrollListener回调的onScrollStateChanged方法中处理,根据RecyclerView.SCROLL_STATE_IDLE == newState状态来计算。
scrollView.setListener(new MyScrollView.MyScrollViewListener() {
@Override
public void onScrollChanged(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
outH = scrollY;
}
});
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (RecyclerView.SCROLL_STATE_IDLE == newState) {
int totalH = itemCount * dip2px(50);
// int outH = scrollView.getScrollY();// 也可以这样获取outH
int seeH = scrollView.getHeight();
int bottomH = totalH - (seeH + outH);
Log.d(TAG, "onScrollStateChanged-停止滑动:" + newState + " 总高:" + totalH
+ " 当前高:" + " item:" + dip2px(50) + " curTop:" + outH + " outH:" + outH + " seeH:" + seeH+" 距离底部:"+bottomH);
}
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
Log.d(TAG, "onScrolled-dx:" + dx + " dy:" + dy);
}
});
<ScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="123dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
</ScrollView>
因为recyclerView高度为match_parent,recyclerView会把所有数据加载进去消耗性能。所以recyclerView是无法滑动的(因为已经显示完了,超出屏幕了只是用户看不到而已)
则可以根据scrollView去滑动.根据recyclerView指定对应的item颜色
recyclerView.smoothScrollToPosition(position);//外层没有scrollView是可以根据position滑动的
if (scrollView != null) {
int count = position - 2;
if (count <= 0) {
scrollView.smoothScrollTo(0, 0);
} else {
scrollView.smoothScrollTo(0, count * CommonUtils.dip2px(80));
}










网友评论