PullToRefreshScrollView滑动监听
PullToRefreshScrollView刷新加载方法是很好用的,所以大家比较喜爱。比如首页我们需要用户可以下拉刷新,那么用这个就再合适不过了。可是如果我需要动态改变导航栏透明度,就需要监听PullToRefreshScrollView当前滑动的位置,但是监听PullToRefreshScrollView滑动状态时,会遇到不少问题。
大家都知道,PullToRefreshScrollView是继承ScrollView的。目前我们监听ScrollView的滑动状态时用的是
但是,会报上述问题。要求23版本的才可以执行此方法,但是实际开发我们一般都是minsdk 4.03以上以适配部分旧机子,所以该方法不能够直接使用。接下来我们就需要在PullToRefreshScrollView里重写一下改监听方法。然而我们在普通的ScrollView里重写该监听是有效的,但是在PullToRefreshScrollView里却是不可以的,在此ScrollView的重写就不在这里写了,直接从PullToRefreshScrollView着手。
通常我们是重写onScrollChanged方法来监听ScrollView滑动状态,但是这里却没有监听到,只有下拉的时候才会触发该监听。然而我们会看到下面一个重写方法
@Override protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { if (mOnScrollChanged != null) { mOnScrollChanged.onScroll(scrollX, scrollY); } final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); // Does all of the hard work... OverscrollHelper.overScrollBy(PullToRefreshScrollView.this, deltaX, scrollX, deltaY, scrollY, getScrollRange(), isTouchEvent); return returnValue; }该方法也有scrollX、scrollY参数,所以我们可以猜测该方法就是拦截的onScrollChanged监听,所以可以根据该方法来实现PullToRefreshScrollView的监听。即将PullToRefreshScrollView重写,重写的PullToRefreshScrollView如下:
PullToRefreshScrollView:
package com.refreshlibrary; import android.annotation.TargetApi; import android.content.Context; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; import android.util.AttributeSet; import android.view.View; import android.widget.ScrollView; public class PullToRefreshScrollView extends PullToRefreshBase<ScrollView> { private OnScrollChanged mOnScrollChanged; public PullToRefreshScrollView(Context context) { super(context); } public PullToRefreshScrollView(Context context, AttributeSet attrs) { super(context, attrs); } public PullToRefreshScrollView(Context context, Mode mode) { super(context, mode); } public PullToRefreshScrollView(Context context, Mode mode, AnimationStyle style) { super(context, mode, style); } public interface OnScrollChanged { void onScroll(int scrollX, int scrollY); } public void setOnScrollChanged(OnScrollChanged onScrollChanged) { this.mOnScrollChanged = onScrollChanged; } @Override public final Orientation getPullToRefreshScrollDirection() { return Orientation.VERTICAL; } @Override protected ScrollView createRefreshableView(Context context, AttributeSet attrs) { ScrollView scrollView; if (VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { scrollView = new InternalScrollViewSDK9(context, attrs); } else { scrollView = new ScrollView(context, attrs); } scrollView.setId(R.id.scrollview); return scrollView; } @Override protected boolean isReadyForPullStart() { return mRefreshableView.getScrollY() == 0; } @Override protected boolean isReadyForPullEnd() { View scrollViewChild = mRefreshableView.getChildAt(0); if (null != scrollViewChild) { return mRefreshableView.getScrollY() >= (scrollViewChild.getHeight() - getHeight()); } return false; } @TargetApi(9) final class InternalScrollViewSDK9 extends ScrollView { public InternalScrollViewSDK9(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) { if (mOnScrollChanged != null) { mOnScrollChanged.onScroll(scrollX, scrollY); } final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); // Does all of the hard work... OverscrollHelper.overScrollBy(PullToRefreshScrollView.this, deltaX, scrollX, deltaY, scrollY, getScrollRange(), isTouchEvent); return returnValue; } /** * Taken from the AOSP ScrollView source */ private int getScrollRange() { int scrollRange = 0; if (getChildCount() > 0) { View child = getChildAt(0); scrollRange = Math.max(0, child.getHeight() - (getHeight() - getPaddingBottom() - getPaddingTop())); } return scrollRange; } } }
其中改动的地方:
定义一个接口interface
public interface OnScrollChanged { void onScroll(int scrollX, int scrollY); }
private OnScrollChanged mOnScrollChanged;
设置监听方法:
public void setOnScrollChanged(OnScrollChanged onScrollChanged) { this.mOnScrollChanged = onScrollChanged; }
在overScrollBy方法里执行监听回掉
@Override protected boolean overScrollBy(int deltaX, int deltaY, int scrollX, int scrollY, int scrollRangeX, int scrollRangeY, int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
if (mOnScrollChanged != null) { mOnScrollChanged.onScroll(scrollX, scrollY); }
final boolean returnValue = super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent); // Does all of the hard work... OverscrollHelper.overScrollBy(PullToRefreshScrollView.this, deltaX, scrollX, deltaY, scrollY, getScrollRange(), isTouchEvent); return returnValue; }
调用的时候:
scrollView.setOnScrollChanged(new PullToRefreshScrollView.OnScrollChanged() { @Override public void onScroll(int scrollX, int scrollY) { } });
比如我要控制标题栏透明度,贴上代码
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <com.refreshlibrary.PullToRefreshScrollView android:id="@+id/mScrollView" android:layout_width="match_parent" android:layout_height="match_parent" android:scrollbars="none"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="\n\n\nH\n\ne\nl\nl\no\n \nW\no\nr\nld!\nH\n\ne\nl\nl\no\n \nW\no\nr\nld!\nH\n\ne\nl\nl\no\n \nW\no\nr\nld!\nH\n\ne\nl\nl\no\n \nW\no\nr\nld!\nH\n\ne\nl\nl\no\n \nW\no\nr\nld!\nH\n\ne\nl\nl\no\n \nW\no\nr\nld!\n" /> </com.refreshlibrary.PullToRefreshScrollView> <RelativeLayout android:id="@+id/rl_head" android:layout_width="match_parent" android:layout_height="48dp"> <View android:id="@+id/view_bg" android:layout_width="match_parent" android:layout_height="match_parent" android:alpha="0" android:background="@color/colorPrimary" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="标题" android:textColor="@color/colorAccent" android:textSize="18sp" /> </RelativeLayout> </RelativeLayout>
MainActivity.java
package com.sy.pulltorefreshscrollviewdemo; import android.app.Activity; import android.os.Bundle; import android.view.View; import com.refreshlibrary.PullToRefreshScrollView; import com.refreshlibrary.PullToRefreshScrollView.OnScrollChanged; public class MainActivity extends Activity { private View bgView; private PullToRefreshScrollView mScrollView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bgView = findViewById(R.id.view_bg); mScrollView = (PullToRefreshScrollView) findViewById(R.id.mScrollView); mScrollView.setOnScrollChanged(new OnScrollChanged() { @Override public void onScroll(int scrollX, int scrollY) { if (scrollY < 500) { bgView.setAlpha((float) scrollY / 500); } } }); } }
顺便写了
源码Demo,以供大家参考,审核过了就会添加链接。