Android scrollTo、scrollBy、以及scroller详解 自定义ViewPager

这篇具有很好参考价值的文章主要介绍了Android scrollTo、scrollBy、以及scroller详解 自定义ViewPager。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Scroller

Android scrollTo、scrollBy、以及scroller详解 自定义ViewPager,Android基础,android

VelocityTracker

VelocityTracker 是一个速度跟踪器,通过用户操作时(通常在 View 的 onTouchEvent 方法中)传进去一系列的 Event,该类就可以计算出用户手指滑动的速度,开发者可以方便地获取这些参数去做其他事情。或者手指滑动超过一定速度并松手,就触发翻页。

CustomViewPager

package com.flannery.androidtools.widgets;

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.Scroller;

/**
 * VelocityTracker is a concept commonly used in computer graphics, physics simulations, and user interface frameworks to calculate the velocity of an object or pointer based on its position over time. It's particularly useful for creating responsive and realistic interactions in applications like games or touch-based user interfaces.
 * In the context of Android development, VelocityTracker refers to a class provided by the Android framework. It's used to track the velocity of motion events, such as touch events, on the screen. This can be useful for implementing various gestures and animations that require knowledge of how quickly a user is moving their finger across the screen.
 * Here's a basic overview of how VelocityTracker works in Android:
 * Initialization: To use VelocityTracker, you need to create an instance of it and associate it with a specific motion event, typically the ACTION_MOVE events in the case of touch gestures.
 * Tracking: As the user interacts with the screen, you feed the VelocityTracker instance with the motion events, which contain the current position of the pointer. The VelocityTracker class calculates the velocity based on the change in position over time.
 * Velocity Retrieval: After you've collected enough motion events, you can retrieve the calculated velocity using the computeCurrentVelocity(int units) method. The units parameter allows you to specify the desired units for the velocity, such as pixels per second.
 *
 * https://www.nhooo.com/note/qadf7m.html
 */
public class CustomViewPager extends ViewGroup {
    private static final String TAG = CustomViewPager.class.getSimpleName();
    private int screenWidth;
    private int screenHeight;
    private int lastMoveX = 0;
    private Scroller scroller; // 滚动计算器
    private VelocityTracker velocityTracker; // 速度跟踪器
    private int MAX_VELOCITY = 600;
    private int curScreen = 0;

    public CustomViewPager(Context context) {
        super(context);
        init(context);
    }

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

    public CustomViewPager(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        scroller = new Scroller(context); // 初始化滚动计算器
        // 添加三个View
        LinearLayout layout1 = new LinearLayout(context);
        layout1.setBackgroundColor(Color.RED);
        addView(layout1);
        LinearLayout layout2 = new LinearLayout(context);
        layout2.setBackgroundColor(Color.GREEN);
        addView(layout2);
        LinearLayout layout3 = new LinearLayout(context);
        layout3.setBackgroundColor(Color.BLUE);
        addView(layout3);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i(TAG, "onTouchEvent: onTouchEvent=" + event);
        if (velocityTracker == null) {
            velocityTracker = VelocityTracker.obtain(); // 初始化滚动速度跟踪器
        }
        velocityTracker.addMovement(event);
        int x = (int) event.getX();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                lastMoveX = x; // 记录下按下的点
                break;
            case MotionEvent.ACTION_MOVE:
                int dis = lastMoveX - x; // 移动的偏移量
                Log.i(TAG, "onTouchEvent: dis=" + dis);
                scrollBy(dis, 0); // 位置滚动
                lastMoveX = x;
                break;
            case MotionEvent.ACTION_UP:
                velocityTracker.computeCurrentVelocity(1000); // 计算需要的位置
                int velocityX = (int) velocityTracker.getXVelocity(); // X轴上的速度
                if (velocityX > MAX_VELOCITY && curScreen > 0) {
                    jump2Screen(curScreen - 1);
                } else if (velocityX < -MAX_VELOCITY && curScreen < getChildCount() - 1) {
                    jump2Screen(curScreen + 1);
                } else {
                    int screen = (getScrollX() + screenWidth / 2) / screenWidth;
                    jump2Screen(screen);
                }
                if (velocityTracker != null) {
                    velocityTracker.recycle();
                    velocityTracker = null;
                }
                break;
        }
        return true;
    }

    public void jump2Screen(int screen) {
        curScreen = screen;
        if (curScreen < 0) {
            curScreen = 0;
        }
        if (curScreen > getChildCount() - 1) {
            curScreen = getChildCount() - 1;
        }
        int dis = curScreen * screenWidth - getScrollX();
        scroller.startScroll(getScrollX(), 0, dis, 0); // 开始滚动
        invalidate();
    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        if (scroller.computeScrollOffset()) { // 是否处于偏移量的位置
            scrollTo(scroller.getCurrX(), 0); // 滚动到指定的位置
            postInvalidate(); // 继续滚动
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        screenWidth = MeasureSpec.getSize(widthMeasureSpec);
        screenHeight = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(screenWidth, screenHeight);
        // 给子View设置大小
        for (int i = 0; i < getChildCount(); i++) {
            View view = getChildAt(i);
            view.measure(screenWidth, screenHeight);
        }
    }


    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int leftWidth = 0;
        // 给子View排班
        for (int i = 0; i < getChildCount(); i++) {
            View view = getChildAt(i);
            view.layout(leftWidth, 0, leftWidth + screenWidth, screenHeight);
            leftWidth = leftWidth + screenWidth;
        }
    }
}

资料

Android scrollTo、scrollBy、以及scroller详解
Android Scroller详解
Android自定义ViewPager实例
Android View 的滚动原理和 Scroller、VelocityTracker 类的使用

Android scrollTo、scrollBy、以及scroller详解 自定义ViewPager,Android基础,android文章来源地址https://www.toymoban.com/news/detail-683651.html

到了这里,关于Android scrollTo、scrollBy、以及scroller详解 自定义ViewPager的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 快速排序 定义、实例详解、与冒泡排序和选择、插入排序的对比,场景举例,以及实战解析

    快速排序(Quick Sort)是对冒泡排序的一种改进,它采用了分治法(Divide and Conquer)的思想解决排序问题。 定义:快速排序的基本思想是将待排序的数据分为三部分:分区点(pivot)、小于分区点的元素(left partition)和大于分区点的元素(right partition)。然后通过递归调用,

    2024年02月03日
    浏览(50)
  • Python开发之Python导包的几种方法,自定义包的生成以及导入详解

    Python是一种跨平台的计算机程序设计语言。 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。 下面介绍python的几种导包方式。 1.

    2024年02月08日
    浏览(30)
  • 滚动条详解:跨平台iOS、Android、小程序滚动条隐藏及自定义样式综合指南

    滚动条是用户界面中的图形化组件,用于指示和控制内容区域的可滚动范围。当元素内容超出其视窗边界时,滚动条提供可视化线索,并允许用户通过鼠标滚轮、触屏滑动或直接拖动滑块来浏览未显示部分,实现内容的上下或左右滚动。它在保持界面整洁、避免内容溢出的同

    2024年04月27日
    浏览(26)
  • 使用scrollTo/scrollTop让页面元素滚动到指定位置, 并设置滚动动画

    当容器有滚动条时,有时需要点击 试图 或 节点 将页面滚动到指定元素位置 比如父元素设置了 overflow: hidden; ,当元素里的内容超过元素本身的高度时, 就会出现滚动条, 那么鼠标滑动的距离就是其滚动距离. scrollTop属性 scrollTop 就是指 “元素中的内容” 超出 “元素上边界” 的

    2023年04月27日
    浏览(65)
  • 如何查看声卡、pcm设备以及tinyplay、tinymix、tinycap的使用 Android tinyAlsa命令详解:

    1、查看当前的声卡: cat /proc/asound/cards 2、查看pcm设备列表: cat /proc/asound/pcm 3、查看当前有哪些进程占用了pcm设备节点 lsof |grep pcm     4、查看有哪些音频设备节点 ls /dev/snd/ 音频设备的命名规则为 [device type] C [card index] D [device index][capture/playback] ,即名字中含有4部分的信息

    2024年02月02日
    浏览(38)
  • vue-virtual-scroller的使用,展示巨量数据,长列表优化,虚拟列表

    计算显示区域的高度(或宽度) 和显示区域的起始位置(scrollTop或scrollLeft) 根据每个元素的尺寸和总数目,计算出整个列表的高度(或宽度) 显示区域的高度(或宽度)和每个元素的尺寸,计算出一页能够显示的元素的数量(即动态计算了可视区域可以显示多少个元素)

    2024年02月14日
    浏览(32)
  • hive的自定义函数以及自定义加密函数

    hive对于敏感数据的加密还不够完善,现在开发一个udf函数,自己设置密钥(hive的加密函数等级比较低,也没有集成自己加密的密钥函数,所以自己开发一个),如果要加密一些数据则可以自己使用特定的密钥进行加密解密,这样很好的方便数据的加密下面将实现过程如下:

    2024年02月08日
    浏览(27)
  • C++命名空间的定义以及使用

    🌏博客主页: 主页 🔖系列专栏: C++ ❤️感谢大家点赞👍收藏⭐评论✍️ 😍期待与大家一起进步! 在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名

    2024年02月02日
    浏览(31)
  • ROS实现自定义信息以及使用

    消息包定义一般如下👇 (1)创建包和依赖项 (2)在新建的qq_msgs的包新建msgs的文件夹,在该文件夹里面新建Carry.msg类型的文件。   其实,Carry.msg就是你自己定义的消息类型,属于qq_msgs包下面的。 (3)在对应CMakeList.txt文件下查看如下信息   查看依赖项是否都满足 (4)选中

    2024年02月13日
    浏览(31)
  • logback自定义调用以及文件输出

      首先五大日志等级是不可更改的,我们所定义的日志输出和调用也是用的这五大等级,这个就不多说了,没啥用。 调用 输出         1、配置xml文件         2、配置调用类封装         3、调用   结果  文件:自己看吧,很简单    

    2024年02月16日
    浏览(23)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包