UGUI ScrollRect滑动定位优化详解
作者:Stephanie_1 发布时间:2021-12-06 09:56:13
UGUI的滑动组件虽然表现上和NGUI的ScrollView一致,但是它更美好的是开放源码的,不了解原理的时候直接查源码就OK。
在使用ScrollRect的时候,想滑动流畅然后定位,既待惯性的滚动设置,如图MovementType指定为Elastic则为带惯性的滑动模式,同时调整Inertia为惯性系数,值越大则惯性表现越大,即滑动手离开后自由滑动到停止所需的时间也越长。Inertia=0时则表示不带惯性,滑动时手离开 滑动即停止。
但是我们既然要用这个组件就是希望它在实现功能的时候体验良好,排除特殊需求,我们当然不希望它一直滚动下去,该停的时候就停,但是如果你检查ScrollRect的源码或直接将滑动中的滚动区坐标变化情况打印出来会发现这个坐标刷新耗时太久了,带惯性的滚动滑动一下就要刷新2甚至更长,坐标变化才会完全结束,如果真等他自然结束我们再做一些如“定位”的操作,真的耗时太长了。因此我想优化一下带惯性的滑动,比如显示它不要自由滑动那么久,加入一个限制时间,比如手离开多长时间就停止滑动。
ScrollRectMe组件在ScrollRect的基础上又增加了两个属性,inertiaMaxTime最大自由滑动的时间和滑动完全结束的事件stopScrollCallback,因为带惯性滚动时OnDrag事件并不能满足需求,那仅仅是手离开就会响应的事件。
2017-6-27更新补充了一下滑动幅度不大的时候或惯性时间都不足设定值inertiaMaxTime 不回调的问题。
最后附上源码:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System;
public class ScrollRectMe : ScrollRect
{
[SerializeField]
public float inertiaMaxTime = 0.5f;//限制惯性持续时间
public Action<GameObject > stopScrollCallback = null;//滑动结束的回调
private float _scrolledTime = 0f;
private Action<GameObject> _stopScrollCallback = null;
private Vector2 _lastPostion = Vector2.zero;
public override void OnEndDrag(PointerEventData eventData)
{
base.OnEndDrag(eventData);
_stopScrollCallback = stopScrollCallback;
_scrolledTime = 0f;
_lastPostion = Vector2.zero;
}
public override void OnDrag(PointerEventData eventData)
{
base.OnDrag(eventData);
_scrolledTime = 0f;
_lastPostion = Vector2.zero;
}
public override void StopMovement()
{
base.StopMovement();
}
protected override void LateUpdate()
{
// base.LateUpdate();
}
private void Update()
{
base.LateUpdate();
}
protected override void SetContentAnchoredPosition(Vector2 position)
{
//2017-6-27 修改补充条件
if (_scrolledTime >= inertiaMaxTime || (position.ToString("0.0") == _lastPostion.ToString("0.0")))
{
if (_stopScrollCallback != null)
{
_stopScrollCallback(transform.gameObject);
_stopScrollCallback = null;
}
_scrolledTime = inertiaMaxTime;
return;
}
base.SetContentAnchoredPosition(position);
_scrolledTime += Time.unscaledDeltaTime;
_lastPostion = position;
}
}
下载地址:ScrollRect优化链接
来源:https://blog.csdn.net/Stephanie_1/article/details/51940616


猜你喜欢
- 线程池合理设置最大线程数和核心线程数工作中有这样一个场景,需要处理千万级别的数据的一个算法,大部分是增删查的操作。这个时候就需要使用多线程去
- AsyncTask是Android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度
- 将SuperSocket封装成类库之后可以将其集成进各种类型的应用,而不仅仅局限于控制台应用程序了,从而应用于不同的场景。这里以Telnet
- 用了MyBatis的同行,应该见过foreach,它一般是这样用的:<select id="foreachTest"
- 目前在公司做一个小东西,里面用到了 FFmpeg 简单处理音视频,感觉功能特别强大,在做之前我写了一个小例子,现在记录一下分享给大家,希望大
- 本文实例讲述了java实现ArrayList根据存储对象排序功能。分享给大家供大家参考,具体如下:与c++中的qsort的实现极为相似,构建
- 首先:看问题图,如下可以激活ide的网址很多,估计是个团队或者个人,直接买了全部产品的一年的有效期。而且还是会一直更新下去的。因为,后来我自
- 在VF、VB、PB的应用中,有些无法通过语言工具本身来完成的或者做得不理想的功能,我们会考虑通过Windows的API来完成。在那个年代,熟
- 一、匿名结构体struct{ char name[20]; int age;}s1;匿名
- Canvas绘制文本时,使用FontMetrics对象,计算位置的坐标。public static class FontMetrics {
- springboot加载yml文件获不到值今天使用spring boot读取yml文件,这种多层嵌套的竟然无法读取到(value注解spri
- 前言:本文源码基于spring-framework-5.3.10。mvc是spring源码中的一个子模块!一、RequestMappingH
- 之前写过一篇 Java 线程池的使用介绍文章《线程池全面解析》,全面介绍了什么是线程池、线程池核心类、线程池工作流程、线程池分类、拒绝策略、
- 在程序设计过程中,我们总是希望自己设计的程序是天衣无缝的,但这几乎又是不可能的。即使程序编译通过,同时也实现了所需要的功能,也并不代表程序就
- 1,IDEA中Lombok作用数据库: 库 表 字段 对应的值 user表(id,name,age)实体对象pojo: 用来封装数据库中的数
- 为什么写?今天去上班的公交上,有朋友在张队(张善友)的微信群里,发了一个介绍C# 6.0新特性的视频,视频7分钟,加上本人英语实在太low,
- Java Hutool 包工具类推荐 ExcelUtil包引入hutool包版本号可根据实际情况更换<dependency> &
- 在Linux中创建一个新进程的唯一方法是使用fork()函数。fork()函数是Linux中一个非常重要的函数,和以往遇到的函数有一些区别,
- Java如何实现线程中断?通过调用Thread类的实例方法interrupt。如下:Thread thread = new Thread()
- 新手当在一个类文件中进行了一些操作之后,会造成sout快捷命令无法自动生成。比如操作了import引入其它包之后。主要是对IDEA操作的不熟