VelocityTrackerView VelocityTracker 与 Scroller 实现View的滑动

详细讲解自定义ViewGroup+Scroller+VelocityTracker做出Launcher滑动 立即下载

VelocityTrackerView 是用 VelocityTracker 与 Scroller 实现View的滑动,继承自ViewGroup,对VelocityTracker,Scroller的学习做个笔记。

VelocityTrackerView.java

import java.util.ArrayList;

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

public class VelocityTrackerView extends ViewGroup {

    public static final String TAG = "VelocityTrackerView";

    public ArrayList<Position> viewPoints;

    private VelocityTracker mVelocityTracker;
    private int mMaximumVelocity;
    private int mMinimumVelocity;
    private Scroller mScroller;
    private int mPointerId; // 触点ID

    private void initOrResetVelocityTracker() {
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        } else {
            mVelocityTracker.clear();
        }
    }

    public VelocityTrackerView(Context context, AttributeSet attrs) {
        super(context, attrs);

        initScrollView();

        viewPoints = new ArrayList<Position>();
    }

    private void initVelocityTrackerIfNotExists() {
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
    }

    private void recycleVelocityTracker() {
        if (mVelocityTracker != null) {
            mVelocityTracker.recycle();
            mVelocityTracker = null;
        }
    }

    private void initScrollView() {
        mScroller = new Scroller(getContext());
        setFocusable(true);
        setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
        setWillNotDraw(false);

        final ViewConfiguration configuration = ViewConfiguration
                .get(getContext());
        mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
        mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        measureChildren(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
        viewPoints.clear();

        //水平排列
        for (int i = 0; i < getChildCount(); i++) {
            View v = getChildAt(i);
            if (i == 0) {
                Position p = new Position();
                p.view = v;
                p.x = 0;
                p.y = 0;
                viewPoints.add(p);
            } else {
                Position p = new Position();
                p.view = v;
                p.y = 0;
                p.x = viewPoints.get(i - 1).x
                        + viewPoints.get(i - 1).view.getWidth();
                viewPoints.add(p);
            }
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            child.setVisibility(View.VISIBLE);
            Position p = viewPoints.get(i);
            child.layout(p.x, p.y, p.x + child.getMeasuredWidth(),
                    p.y + child.getMeasuredHeight());
            if (i % 2 == 1) {
                child.setBackgroundColor(Color.parseColor("#FF666633"));
            } else {
                child.setBackgroundColor(Color.parseColor("#FFaa1122"));
            }
        }
    }

    float mLastMotionX;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        initVelocityTrackerIfNotExists();
        mVelocityTracker.addMovement(event);

        final float x = event.getX();
        final float y = event.getY();

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            mPointerId = event.getPointerId(0);
            initOrResetVelocityTracker();
            
            if (!mScroller.isFinished()) {
                mScroller.abortAnimation();  //禁止滑动
            }
            mLastMotionX = x;

        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            // 求伪瞬时速度
            mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
            final int velocityX = (int) mVelocityTracker
                    .getXVelocity(mPointerId);
            if ((Math.abs(velocityX) > mMinimumVelocity) && getChildCount() > 0) {
                fling(-velocityX);
            }
            recycleVelocityTracker();
        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {

            int deltaX = (int) (mLastMotionX - x);
            mLastMotionX = x;
            //随着手指滚动
            scrollBy(deltaX, 0);
        } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
            recycleVelocityTracker();
        }
        return true;
    }

    /**
     *  滑动
     * @param velocityX
     */
    public void fling(int velocityX) {
        
        if (getChildCount() > 0) {
            //设置Scroller的滑动参数
            mScroller.fling(getScrollX(), getScrollY(), velocityX, 0, 0, 10000,
                    0, 0);
             //这里必须调用postInvalidate()才能保证computeScroll()会被调用,否则不一定会刷新界面,看不到滚动效果
            postInvalidate();
        }
    }

    @Override
    public void computeScroll() {

         //先判断mScroller滚动是否完成
        if (mScroller.computeScrollOffset()) {
            int scrollX = getScrollX();
            int scrollY = getScrollY();
            int oldX = scrollX;
            int oldY = scrollY;
            int x = mScroller.getCurrX();
            int y = mScroller.getCurrY();
            scrollX = x;
            scrollY = y;
            scrollY = scrollY + 10;
            //这里调用View的scrollTo()完成实际的滚动
            scrollTo(scrollX, scrollY);
            postInvalidate();  //这里必须调用postInvalidate()才能保证computeScroll()会被调用,否则不一定会刷新界面,看不到滚动效果
        }
    }

    public class Position {
        int x;
        int y = 0;
        int width;
        View view;
    }
}

xml中使用:

    <com.example.cyclingimage.VelocityTrackerView
        android:id="@+id/velocityTrackerView1"
        android:layout_width="wrap_content"
        android:layout_height="400dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" >
          <TextView
            android:layout_width="300dp"
            android:layout_height="400dp"
            android:text="1" />
        <TextView
            android:layout_width="300dp"
            android:layout_height="400dp"
            android:text="2" />
        <TextView
            android:layout_width="300dp"
            android:layout_height="400dp"
            android:text="3" />
        <TextView
            android:layout_width="300dp"
            android:layout_height="400dp"
            android:text="4" />
        <TextView
            android:layout_width="300dp"
            android:layout_height="400dp"
            android:text="5" />
         
    </com.example.cyclingimage.VelocityTrackerView>

腾讯2020 unreal虚幻面试题 解析一下,腾讯的unreal客户端面试题: 1.lua性能优化的方向 申请的内存,是造成卡顿的原因之一,在C++与lua交互中,如果参数或者返回值有类变量,那么这个变量不会再交互的栈中存放数据,而会通过申请内存,再指定在交互,这样就造成卡顿,因此可以通过把C++的对象的每个参数分开单独传递,可以解决问题,当时我们游戏改完这个问题后,整体提升了2帧。 其实,主要是Tick循环中,减少与C++的交互,需要的数据不要每帧都去拿,其次,经常拿的一些数据(比方说主角信息),可以做一个lua缓存,... 阅读详情

相关推荐

深入分析大众点评 Ajax 接口:直接请求 JSON 数据高效获取评论

大众点评网站采用前后端分离架构,通过Ajax接口动态加载数据。按F12打开开发者工具,切换到Network(网络)面板。实际环境中,我们需要使用Python重现这一加密逻辑。查看请求响应,寻找包含评论数据的JSON接口。参数是大众点评的反爬机制核心,需要特别处理。:尊重网站的robots.txt文件规定。:仅将数据用于合法合规的研究和分析目的。:不侵犯大众点评的商业秘密和知识产权。打开大众点评网站,进入任意商户页面。:对采集到的用户信息进行脱敏处理。:避免对目标网站造成过大负担。

Z_suger7的博客 1584

Android的Scroller和VelocityTracker

一. Android的Scroller介绍     public class Scroller extends Object     java.lang.Object      android.widget.Scroller二. 概述 这个类封装了滚动操作。滚动的持续时间可以通过构造函数传递,并且可以指定滚动动作的持续的最长时间。经过这段时间,滚动会自动定位到最终位置,并且通过computeScro

0.0 996

【SigmaStar SSC335系列】空片用Flash_Tool烧写

简介 本文主要讲新拿到的PCBA,板上spi nand flash还是空的,如何在这种情况下烧录固件,这里讲解用官方Flash_Tool烧写的方式。 但只讲一些注意的地方和坑,其它的官方文档里说的比较清楚,不多说。 准备 Flash_Tool烧写软件 编译打包好烧写镜像 串口烧录小板 ----- 这个是个坑,在官方文档里并没有提及,刚开始用的平时调试的USB转串口,怎么都没反应,一度不知烧写软件不对还是硬件有问题,最后通过厂家技术支持才得知,除了专门的Flash_Tool外,还要专门的串口烧录器

老K 4699

让控件如此丝滑Scroller和VelocityTracker的API讲解与实战——Android高级UI

目录 一、前言 二、Scroller 三、VelocityTracker 四、实战——带惯性滑动的柱状图 五、写在最后 一、前言 自定义控件中,难免会遇到需要滑动的场景。而Canvas提供的scrollTo和scrollBy方法只能达到移动的效果,需要达到真正的滑动便需要我们今天分享的两把基础利器Scroller和VelocityTracker。老规矩,先上实战图,再进行分享。 带惯性滑动的柱...

weixin_34010949的博客 658

23. STM32F103C8T6 ADC采集光敏电阻传感器模块光照强度实战

本文详细介绍了如何使用STM32F103C8T6的ADC模块采集光敏电阻传感器的光照强度。通过硬件接线、核心原理讲解、四步代码配置(GPIO、ADC模式、使能校准、数据滤波)以及串口验证,手把手指导完成从模拟信号到数字值的完整实战流程,并重点提示了ADC时钟分频等关键配置要点。

weixin_42300144的博客 221

保姆级教程 | MS构建三层石墨后转成LAMMPS的data文件

喜欢的话记得一键三连~

baguette的博客 2952

OverScroller、VelocityTracker、ViewConfiguration综合使用达到炫酷效果

问题来源在android应用程序的开发过程中,相信我们很多人都想把应用的交互做的比较绚丽,比如让界面切换平滑的滚动,还有热度灰常高的伪3D等界面效果,通常情况下,系统提供的应用在特效这方面只能为我们提供简单的动画接口,所以要想实现比较酷炫的效果还是要自己去开发布局控件(即所谓的自定义View、ViewGroup)。ScrollVIew无法解决问题下面就我最近工作中遇到的一个自定义控件开发做一些简单的

coder_nice的专栏 1671

中国1990-2021连续30年土地利用CLCD数据分享

CLCD(China Land Cover Dataset)数据集是由武汉大学黄昕老师基于Google Earth Engine上的335,709景Landsat数据制作的中国年度土地覆盖数据集。为了提高CLCD的时空一致性,还提出了一种包含时空滤波和逻辑推理的后处理方法。该数据集最大的优势在于每年30米的土地利用分类结果,且连续覆盖了30年时间。相比其他产品如GLC_FCS30、Global30、AGLC2000_2015、FROM-GLC10、ESA10、ESRI10等,CLCD在时间分辨率上更高。

qq_48539301的博客 1万+

Android Scroller和VelocityTracker类

1. scrollXX()方法 scrollTo()和scrollBy()是用于滑动View中的内容 scrollTo(int x, int y) // 将View中内容滑动到相应的位置 scrollBy(int x, int y) // 将View中内容滑动相对的位置 对于一个View来说,有一个View视图和一个Canvas。滑动时会移动View视图,显示不同的Canvas部分。 下面例子中...

假装你是大灰狼的专栏 784

【Qt开发教程】网络代理QNetworkProxy类详解及实战应用

QNetworkProxy 提供了一种灵活而强大的方式来配置和管理网络代理,通过设置代理类型、主机、端口和认证信息,可以使应用程序的所有网络请求通过代理服务器进行。结合 QNetworkProxyFactory 可以实现动态代理选择和自动配置,提高应用的网络通信能力和安全性。在实际应用中,通过合理设置代理、处理代理认证和错误情况,可以确保应用程序在复杂的网络环境中稳定运行,为用户提供可靠的网络访问体验。

科技改变人类,技术成就未来 1542

YOLOv11改进策略【模型轻量化】| 替换骨干网络 CVPR-2024 RepViT 轻量级的Vision Transformers架构

本文记录的是基于RepVit的YOLOv11轻量化改进方法研究。RepVit的网络结构借鉴ViT的设计理念,通过分离的token mixe和减少推理时的计算和内存成本,同时减少扩展比率并增加宽度,降低延迟,并通过来弥补参数大幅减少的问题,提高了准确性。本文在替换骨干网络中配置了原论文中的和五种模型,以满足不同的需求。

Limiiiing的博客 2976

ViewTracker - 自动化UI交互事件采集利器

ViewTracker - 自动化UI交互事件采集利器 在移动应用开发中,用户行为数据的收集对于产品优化和用户体验提升至关重要。ViewTracker 是一个专为 iOS 平台设计的开源项目,旨在自动化采集用户在应用中的UI交互事件,包括曝光和点击事件。本文将详细介绍 ViewTracker 的项目特点、技术分析以及应用场景,帮助开发者更好地理解和使用这一工具。 项目介绍 ViewTracker ...

gitblog_00028的博客 734

RK3568平台开发系列讲解(音频篇)配置声卡

📢本篇文章介绍如何配置声卡。

内核笔记 2448

关于Android滑动scroll,弹性滑动以及VelocityTracker

一 VelocityTracker 速度追踪,手指在滑动中的速度,包括水平和竖直方向。 计算公式: 速度 =(终点位置-起点位置)/ 时间段 使用: VelocityTracker velocityTracker= VelocityTracker.obtain() ; velocityTracker.addMovement(event); velocityTracker.computeCurrentVelocity(1000); int xVelocity = (int) velocity

LJ_GOD的博客 721

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

庖丁解牛之ScrollView

庖丁解牛之ScrollView前言ScrollView可以说是android里最简单的滑动控件,但是其中也蕴含了很多的知识点。今天尝试通过ScrollView的源码来了解ScrollView内部的细节。本文在介绍ScrollView时会忽略以下内容:嵌套滑动,崩溃保存,Accessibility。 ScrollView是一种控件,继承自 FrameLayout,他的子控件远远大于ScrollVie

litefish的专栏 1万+

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Scroller&&VelocityTracker

一、VelocityTracker VelocityTracker是根据我们手指触摸事件,计算出滑动速度的工具类,Api比较简单 获取VelocityTracker对象 static public VelocityTracker obtain() recycle() // 回收VelocityTracker对象 clear() // 重置VelocityTracker回其初始状态 传入触摸事件,才能之后调用computeCurrentVelocity正确的得到当前速度。 ...

杨文浩_boke 412

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

代码讲解Android Scroller、VelocityTracker

在编写自定义滑动控件时常常会用到Android触摸机制和Scroller及VelocityTracker。Android Touch系统简介(二):实例详解onInterceptTouchEvent与onTouchEvent的调用过程对Android触摸机制需要用到的函数进行了详细的解释,本文主要介绍两个重要的类:Scroller及VelocityTracker。利用上述知识,最后给出了一个自

bigconvience的专栏 1万+

彻底解决监听Scrollview滑动暂停问题

项目中有个功能要监听Scrollview的滑动暂停状态,百度了一下,都是通过handler机制来比较getScrollY()值来实现,这种方式还是有bug的,在滑动中停止为撒手状态下,或者在底部,头部的时候有监听不到的情况。后来我就想着Scrollview内部有没有滑动停止的标志呢。阅读Scrollview源码之后发现还真有!!!这个滑动事件肯定和onTouchEvent(MotionEvent e

doctorzhong的博客 3505

android自定义View-垂直滚动的TextView

其实要让TextView能够滚动,可以使用ScrollView/HorizontalScrollView或者设置ScrollingMovementMethod来实现。点击查看:android实现TextView垂直或水平滚动 下面自定义垂直滚动的TextView,主要是用来学习Scroller的使用。关于ScrollTextView的实现,可以看下面的介绍和源码。 package com....

weixin_33859665的博客 81

scrollTo与scrollBy用法以及TouchSlop与VelocityTracker解析

最近在工作中使用到了scrollTo与scrollBy,因此在这准备对它们的用法以及TouchSlop与VelocityTracker做一下整理与总结,以便加深理解,以下是本篇的主要内容,至于Scroller类的解析以及用法,我会放在下一篇文件记录。 直接开始吧。 1.view相关位置参数 1.1 Android坐标系 在物理学中,描述一个物体的运动通常都需要选

zejian的博客 3457

【Android 手势冲突】Colin带你彻底解决RecyclerView与ScrollView滑动冲突问题,并实现RecyclerView悬停导航栏(附demo哦)

在新一期的需求中,产品要求我们做出和美团某个页面类似的功能,即一个页面包含在scrollView中,上面一个部分放置一些常用的广告banner、宫格tab等,下面放置一个RecyclerView用于展示具体的产品列表。 要想实现上述功能,不可避免地要用到ScrollView嵌套RecyclerView。为什么要用RecyclerView?因为下面的产品列表项非常多,有60条,如果一次性加...

你关注了我,是个概率极低的事件...... 2万+

Android Scroll具体解释(二):OverScroller实战

作者: ztelur 联系方式:segmentfault,csdn。github 本文仅供个人学习,不用于不论什么形式商业目的,转载请注明原作者、文章来源。链接,版权归原文作者全部。  本文是android滚动相关的系列文章的第二篇,主要总结一下使用手势相关的代码逻辑。主要是单点拖动,多点拖动,fling和OveScroll的实现。每一个手势都会有代码片段。  ...

weixin_33804582的博客 279

天天记录 - 使用VelocityTracker计算滑动速率

先看看效果图   使用比较简单,直接贴代码 /** * 计算滑动速率 * */ public class VelocityTrackerDemoActivity extends Activity { private static final String INFO = "手指在屏幕上滑动"; private int mMaximumV

Android 3263

实现拖动控制神器 ViewDragHelper 的简单学习

上一篇学习了 android里可以进行scroll 的 4 个方法,还有一个重要的 ViewDragHelper ,在这里重点学习一下。首先我们先把这个ViewDragHelper 的框架先搭建起来,让它里的View 可以随意拖动。首先自定义一个View 继承 ViewGroup ,先来一个完成代码,后面学习细节package mw.huawei.com.viewdraghelper.MyView...

空中的晨曦博客 446

VelocityTracker简单用法

VelocityTracker顾名思义即速度跟踪,在android中主要应用于touch event, VelocityTracker通过跟踪一连串事件实时计算出 当前的速度,这样的用法在android系统空间中随处可见,比如Gestures中的Fling, Scrolling等,下面简单介绍一下用法。 //获取一个VelocityTracker对象, 用完后记得回收 //回收后代表你不需

bingxianwu的专栏 1万+

自定义控件 ——可拖动测量尺子

原创作者地址:http://blog.youkuaiyun.com/tl792814781/article/details/52388577 前言: 最近做的一个项目,有个界面是 输入框输入数值的,后来产品觉得键盘输入麻烦,就换成了这样子,这是前几天Ui小伙子设计的界面: 分析: 其实简单的画一个测量尺子刻度控件并不会太难,其次就是被5和10整除的刻度线高度

Coding_the_world 4090
上一篇: android — JNI注册方法说明
下一篇: Activity设置singleInstance后不能启用startActivityForResult()进行数据回调
CYoung
博客等级 码龄15年 25粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值