怎样判断 android ScrollView 是否滚到底部 -chatgat版本

  • 怎样判断 android ScrollView 是否滚到底部

您可以使用以下代码来判断ScrollView是否到达底部:

ScrollView scrollView = findViewById(R.id.scroll_view);

// 获取ScrollView的高度
int scrollViewHeight = scrollView.getHeight();

// 获取ScrollView的子View
View lastChild = scrollView.getChildAt(scrollView.getChildCount() - 1);

// 获取ScrollView的子View的Y轴坐标
int lastChildBottomY = lastChild.getBottom();

// 获取ScrollView的滚动位置
int scrollY = scrollView.getScrollY();

// 判断滚动位置是否到达底部
if (scrollY + scrollViewHeight >= lastChildBottomY) {
    // 到达底部
}

其中 scrollY + scrollViewHeight 表示ScrollView当前的底部Y轴坐标,lastChildBottomY 表示ScrollView中最后一个子View的底部Y轴坐标。如果 scrollY + scrollViewHeight 大于或等于 lastChildBottomY,则ScrollView已经滚动到底部。

  • 有上下padding判断一样吗

当ScrollView存在上下Padding时,判断是否滚动到底部的逻辑与没有Padding时略有不同。此时可以使用以下代码来判断是否滚动到底部:

ScrollView scrollView = findViewById(R.id.scroll_view);

// 获取ScrollView的可视高度
int visibleHeight = scrollView.getHeight() - scrollView.getPaddingTop() - scrollView.getPaddingBottom();

// 获取ScrollView的子View
View lastChild = scrollView.getChildAt(scrollView.getChildCount() - 1);

// 获取ScrollView的子View的底部位置
int lastChildBottom = lastChild.getBottom();

// 获取ScrollView的滚动位置
int scrollY = scrollView.getScrollY();

// 计算ScrollView底部位置
int scrollViewBottom = scrollY + visibleHeight;

// 判断ScrollView是否滚动到底部
if (scrollViewBottom >= lastChildBottom) {
    // 到达底部
}

其中,scrollView.getHeight() 指的是 ScrollView 的可视高度,也就是除去上下 padding 后的高度;scrollView.getPaddingTop() 和 scrollView.getPaddingBottom() 分别获取 ScrollView 的上下 padding 值。

计算 ScrollView 的底部位置时,将滚动的 Y 轴坐标 scrollY 加上可视高度 visibleHeight 就得到了 ScrollView 的底部位置。然后判断 ScrollView 的底部是否大于等于它的最后一个子 View 的底部位置 lastChildBottom,如果是,就表明 ScrollView 已经滚动到了底部。

  • 有padding和没有padding可以结合判断吗

可以结合上述两种方法,对 ScrollView 是否滚动到底部进行判断:

ScrollView scrollView = findViewById(R.id.scroll_view);

// 获取 ScrollView 的可视高度
int visibleHeight = scrollView.getHeight() - scrollView.getPaddingTop() - scrollView.getPaddingBottom();

// 获取 ScrollView 的子View
View lastChild = scrollView.getChildAt(scrollView.getChildCount() - 1);

// 获取 ScrollView 可以滑动的范围
int scrollRange = scrollView.getChildAt(0).getHeight() - scrollView.getHeight();

// 获取 ScrollView 的滚动位置
int scrollY = scrollView.getScrollY();

// 判断 ScrollView 是否滚动到底部
if (scrollY == scrollRange) {
    // 已滑动到底部
    return true;
} else if (scrollViewBottom >= lastChildBottom) {
    // scrollTo 和 scrollTo 不是同时回调,所以添加两个逻辑都可(可根据需要决定是否需要使用两个逻辑组合)
    // 已滑动到底部
    return true;
} else {
    // 未滑动到底部
    return false;
}

其中,scrollRange 是整个 ScrollView 可以滑动的范围,即第一个子 View 的高度减去 ScrollView 的高度。如果 scrollY 的值等于 scrollRange 则表明 ScrollView 已经到达底部。接下来,根据上下 padding 情况,可以使用第一种方法或第二种方法来判断是否到达底部。

上述代码把 ScrollView 是否滚动到底部的判断条件划分为两个部分,先判断是否到达滑动范围的底部(即是否滑动到底部)。如果未到达滑动范围的底部,则根据上下 padding 情况使用不同的方法再次对 ScrollView 是否到达底部进行判断。

  • 可以通过自定义方式进行内部封装判断吗

可以通过自定义一个继承自 ScrollView 的类,在该类中添加一个方法来判断 ScrollView 是否滚动到底部。

这种方式的好处就是可以将判断 ScrollView 是否滚动到底部的逻辑封装在一个类中,不需要每次操作 ScrollView 都编写重复的代码。下面是一个示例:

public class MyScrollView extends ScrollView {
    
    public MyScrollView(Context context) {
        super(context);
    }

    public MyScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    
    public boolean isScrolledToBottom() {
        if (getChildCount() == 0) {
            return true;
        }

        int scrollViewHeight = getHeight();
        int scrollY = getScrollY();
        View lastChild = getChildAt(getChildCount() - 1);
        int lastChildBottom = lastChild.getBottom() + getPaddingBottom();

        if (scrollY + scrollViewHeight >= lastChildBottom) {
            return true;
        } else {
            return false;
        }
    }
}

在上面的代码中,首先继承自 ScrollView,在 isScrolledToBottom() 方法中添加了 ScrollView 是否到达底部的逻辑,其中,getChildCount() 方法用来获取 ScrollView 的子 View 的数量;getScrollY()方法用来获取 ScrollView 的滚动位置;getChildAt() 方法用来获取 ScrollView 的子 View;getPaddingBottom() 方法用来获取 ScrollView 的下 padding。最后判断 ScrollView 是否到达底部。

这样,在使用 MyScrollView 的时候,只需要调用 isScrolledToBottom() 方法就能判断 ScrollView 是否滚动到了底部。

  • 上面自定义考虑到了上下padding的情况吗?

很抱歉,我之前自定义类的回答并没有考虑到上下 Padding 的情况。这里提供一个带有上下 Padding 的判断方法的自定义 ScrollView 类:

public class CustomScrollView extends ScrollView {
    
    public CustomScrollView(Context context) {
        super(context);
    }

    public CustomScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    /**
     * 判断 ScrollView 的滑动位置是否到达底部
     * @return  true 表示到达底部,false 表示未到达底部
     */
    public boolean isScrolledToBottom() {
        if (getChildCount() == 0) {
            return true;
        }

        int scrollViewHeight = getHeight() - getPaddingTop() - getPaddingBottom();
        int scrollY = getScrollY() + getPaddingTop();
        View lastChild = getChildAt(getChildCount() - 1);
        int lastChildBottom = lastChild.getBottom() + ((MarginLayoutParams) lastChild.getLayoutParams()).bottomMargin;

        if (scrollY + scrollViewHeight >= lastChildBottom) {
            return true;
        }

        return false;
    }
}

在这个自定义 ScrollView 类中,我们重写了 isScrolledToBottom() 方法,这个方法的实现方式和之前在ScrollView中提供的方法类似,不同之处在于这里将上下 Padding 也计算进去了。

具体而言,以上述代码为例,首先使用 getHeight() 方法获取了 ScrollView 的可显示高度,然后使用 getScrollY() 方法获取了 ScrollView 的滚动位置,接下来获取了 ScrollView 最后一个子 View 的底部位置,这里的底部位置需要加上子 View 的底部 Margin,最后将 Padding 也计算进去,就得到了 ScrollView 底部的位置。通过判断 ScrollView 最底端的位置是否小于或等于 ScrollView 的底部位置,就可以判断 ScrollView 是否滑动到了底部。

您可以使用以下代码来判断ScrollView是否到达底部:

ScrollView scrollView = findViewById(R.id.scroll_view);

// 获取ScrollView的高度
int scrollViewHeight = scrollView.getHeight();

// 获取ScrollView的子View
View lastChild = scrollView.getChildAt(scrollView.getChildCount() - 1);

// 获取ScrollView的子View的Y轴坐标
int lastChildBottomY = lastChild.getBottom();

// 获取ScrollView的滚动位置
int scrollY = scrollView.getScrollY();

// 判断滚动位置是否到达底部
if (scrollY + scrollViewHeight >= lastChildBottomY) {
    // 到达底部
}

其中 scrollY + scrollViewHeight 表示ScrollView当前的底部Y轴坐标,lastChildBottomY 表示ScrollView中最后一个子View的底部Y轴坐标。如果 scrollY + scrollViewHeight 大于或等于 lastChildBottomY,则ScrollView已经滚动到底部。

  • 有上下padding判断一样吗

当ScrollView存在上下Padding时,判断是否滚动到底部的逻辑与没有Padding时略有不同。此时可以使用以下代码来判断是否滚动到底部:

ScrollView scrollView = findViewById(R.id.scroll_view);

// 获取ScrollView的可视高度
int visibleHeight = scrollView.getHeight() - scrollView.getPaddingTop() - scrollView.getPaddingBottom();

// 获取ScrollView的子View
View lastChild = scrollView.getChildAt(scrollView.getChildCount() - 1);

// 获取ScrollView的子View的底部位置
int lastChildBottom = lastChild.getBottom();

// 获取ScrollView的滚动位置
int scrollY = scrollView.getScrollY();

// 计算ScrollView底部位置
int scrollViewBottom = scrollY + visibleHeight;

// 判断ScrollView是否滚动到底部
if (scrollViewBottom >= lastChildBottom) {
    // 到达底部
}

其中,scrollView.getHeight() 指的是 ScrollView 的可视高度,也就是除去上下 padding 后的高度;scrollView.getPaddingTop() 和 scrollView.getPaddingBottom() 分别获取 ScrollView 的上下 padding 值。

计算 ScrollView 的底部位置时,将滚动的 Y 轴坐标 scrollY 加上可视高度 visibleHeight 就得到了 ScrollView 的底部位置。然后判断 ScrollView 的底部是否大于等于它的最后一个子 View 的底部位置 lastChildBottom,如果是,就表明 ScrollView 已经滚动到了底部。

  • 有padding和没有padding可以结合判断吗

可以结合上述两种方法,对 ScrollView 是否滚动到底部进行判断:

ScrollView scrollView = findViewById(R.id.scroll_view);

// 获取 ScrollView 的可视高度
int visibleHeight = scrollView.getHeight() - scrollView.getPaddingTop() - scrollView.getPaddingBottom();

// 获取 ScrollView 的子View
View lastChild = scrollView.getChildAt(scrollView.getChildCount() - 1);

// 获取 ScrollView 可以滑动的范围
int scrollRange = scrollView.getChildAt(0).getHeight() - scrollView.getHeight();

// 获取 ScrollView 的滚动位置
int scrollY = scrollView.getScrollY();

// 判断 ScrollView 是否滚动到底部
if (scrollY == scrollRange) {
    // 已滑动到底部
    return true;
} else if (scrollViewBottom >= lastChildBottom) {
    // scrollTo 和 scrollTo 不是同时回调,所以添加两个逻辑都可(可根据需要决定是否需要使用两个逻辑组合)
    // 已滑动到底部
    return true;
} else {
    // 未滑动到底部
    return false;
}

其中,scrollRange 是整个 ScrollView 可以滑动的范围,即第一个子 View 的高度减去 ScrollView 的高度。如果 scrollY 的值等于 scrollRange 则表明 ScrollView 已经到达底部。接下来,根据上下 padding 情况,可以使用第一种方法或第二种方法来判断是否到达底部。

上述代码把 ScrollView 是否滚动到底部的判断条件划分为两个部分,先判断是否到达滑动范围的底部(即是否滑动到底部)。如果未到达滑动范围的底部,则根据上下 padding 情况使用不同的方法再次对 ScrollView 是否到达底部进行判断。

可以通过自定义方式进行内部封装判断吗

可以通过自定义一个继承自 ScrollView 的类,在该类中添加一个方法来判断 ScrollView 是否滚动到底部。

这种方式的好处就是可以将判断 ScrollView 是否滚动到底部的逻辑封装在一个类中,不需要每次操作 ScrollView 都编写重复的代码。下面是一个示例:

public class MyScrollView extends ScrollView {
    
    public MyScrollView(Context context) {
        super(context);
    }

    public MyScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    
    public boolean isScrolledToBottom() {
        if (getChildCount() == 0) {
            return true;
        }

        int scrollViewHeight = getHeight();
        int scrollY = getScrollY();
        View lastChild = getChildAt(getChildCount() - 1);
        int lastChildBottom = lastChild.getBottom() + getPaddingBottom();

        if (scrollY + scrollViewHeight >= lastChildBottom) {
            return true;
        } else {
            return false;
        }
    }
}

在上面的代码中,首先继承自 ScrollView,在 isScrolledToBottom() 方法中添加了 ScrollView 是否到达底部的逻辑,其中,getChildCount() 方法用来获取 ScrollView 的子 View 的数量;getScrollY()方法用来获取 ScrollView 的滚动位置;getChildAt() 方法用来获取 ScrollView 的子 View;getPaddingBottom() 方法用来获取 ScrollView 的下 padding。最后判断 ScrollView 是否到达底部。

这样,在使用 MyScrollView 的时候,只需要调用 isScrolledToBottom() 方法就能判断 ScrollView 是否滚动到了底部。

上面自定义考虑到了上下padding的情况吗?

很抱歉,我之前自定义类的回答并没有考虑到上下 Padding 的情况。这里提供一个带有上下 Padding 的判断方法的自定义 ScrollView 类:

public class CustomScrollView extends ScrollView {
    
    public CustomScrollView(Context context) {
        super(context);
    }

    public CustomScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    /**
     * 判断 ScrollView 的滑动位置是否到达底部
     * @return  true 表示到达底部,false 表示未到达底部
     */
    public boolean isScrolledToBottom() {
        if (getChildCount() == 0) {
            return true;
        }

        int scrollViewHeight = getHeight() - getPaddingTop() - getPaddingBottom();
        int scrollY = getScrollY() + getPaddingTop();
        View lastChild = getChildAt(getChildCount() - 1);
        int lastChildBottom = lastChild.getBottom() + ((MarginLayoutParams) lastChild.getLayoutParams()).bottomMargin;

        if (scrollY + scrollViewHeight >= lastChildBottom) {
            return true;
        }

        return false;
    }
}

在这个自定义 ScrollView 类中,我们重写了 isScrolledToBottom() 方法,这个方法的实现方式和之前在ScrollView中提供的方法类似,不同之处在于这里将上下 Padding 也计算进去了。

具体而言,以上述代码为例,首先使用 getHeight() 方法获取了 ScrollView 的可显示高度,然后使用 getScrollY() 方法获取了 ScrollView 的滚动位置,接下来获取了 ScrollView 最后一个子 View 的底部位置,这里的底部位置需要加上子 View 的底部 Margin,最后将 Padding 也计算进去,就得到了 ScrollView 底部的位置。通过判断 ScrollView 最底端的位置是否小于或等于 ScrollView 的底部位置,就可以判断 ScrollView 是否滑动到了底部。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,734评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,931评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,133评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,532评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,585评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,462评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,262评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,153评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,587评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,792评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,919评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,635评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,237评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,855评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,983评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,048评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,864评论 2 354

推荐阅读更多精彩内容