PullToRefreshScrollView滑动监听问题

本文介绍如何在PullToRefreshScrollView中实现滑动监听,以便动态改变导航栏透明度等效果。通过重写overScrollBy方法并定义OnScrollChanged接口实现滑动位置的监听。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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,以供大家参考,审核过了就会添加链接。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值