当前位置: 首页 > news >正文

unity双层滑动实现

实现功能:
当滑动列表中内容处于顶端的时候,向上滑动优先滑动整个滑动列表,当滑动列表移动到设置位置,即设定的最高处时,继续移动列表内内容。向下移动亦然,当内容处于滑动列表顶端时,移动整个滑动列表。

eventtriggerlistener脚本可在这篇查看unity防止ui点击事件被子物体拦截

using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;public class ScrollViewMove : MonoBehaviour
{public ScrollRect m_scorllView;public RectTransform m_rectView;private void Start(){//添加滑动事件Graphic horizontalGraphic = m_scorllView.GetComponent<Graphic>();if (horizontalGraphic != null && horizontalGraphic.raycastTarget){EventTriggerListener.Get(m_scorllView.gameObject).onBeginDrag = OnScrollBeginDrag;EventTriggerListener.Get(m_scorllView.gameObject).onDrag = OnScrollDrag;EventTriggerListener.Get(m_scorllView.gameObject).onEndDrag = OnScrollEndDrag;}//设置最高高度,和出现滑动时的阈值m_minHeight = m_scorllView.GetComponent<RectTransform>().localPosition.y;m_LimitY = (m_maxHeight - m_minHeight) * MOVE_DISTANCE_SCALE;}#region 滑动条事件//起始滑动位置private float m_startScrollHeight = 0f;//结束滑动位置private float m_endScrollHeight = 0f;//限制切换动画的最小判断private float m_LimitY;private readonly float MOVE_DISTANCE_SCALE = 0.2f;//起始鼠标位置private float m_startMouseHeight = 0f;//中途鼠标位置private float m_partMouseHeight = 0f;//最大高度private float m_maxHeight = 0f;//最小高度private float m_minHeight = 0f;//是否为展开状态private bool m_isOpen = false;/// <summary>/// 滑动列表开始拖拽事件/// </summary>/// <param name="obj"></param>private void OnScrollBeginDrag(GameObject obj){m_startScrollHeight = m_scorllView.GetComponent<RectTransform>().localPosition.y;m_startMouseHeight = Input.mousePosition.y;}/// <summary>/// 滑动列表拖拽事件/// 先判断走拖拽事件还是滑动列表滑动事件/// </summary>/// <param name="obj"></param>private void OnScrollDrag(GameObject obj){m_partMouseHeight = Input.mousePosition.y;float m_offsetHeight = m_partMouseHeight - m_startMouseHeight;m_startMouseHeight = m_partMouseHeight;float scrollPosY = m_scorllView.GetComponent<RectTransform>().localPosition.y;if (scrollPosY >= m_maxHeight){if (m_offsetHeight >= 0){m_scorllView.vertical = true;return;}else{if (m_scorllView.verticalNormalizedPosition < 1){m_scorllView.vertical = true;return;}}}else if (scrollPosY <= m_minHeight){if (m_offsetHeight <= 0){m_scorllView.vertical = true;return;}else{if (m_scorllView.verticalNormalizedPosition > 1){m_scorllView.vertical = true;return;}}}m_scorllView.verticalNormalizedPosition = 1;m_scorllView.vertical = false;OnPosDrag(m_offsetHeight);}/// <summary>/// 设置滑动位置/// </summary>/// <param name="offset"></param>private void OnPosDrag(float offset){//设置滑动列表位置Vector3 scrollPos = m_scorllView.GetComponent<RectTransform>().localPosition;float endPosY = scrollPos.y + offset;if (endPosY > m_maxHeight){offset = m_maxHeight - scrollPos.y;}else if (endPosY < m_minHeight){offset = m_minHeight - scrollPos.y;}scrollPos = new Vector3(scrollPos.x, scrollPos.y + offset, scrollPos.z);m_scorllView.GetComponent<RectTransform>().localPosition = scrollPos;//设置滑动列表遮罩大小Vector2 viewPos = m_rectView.offsetMin;viewPos = new Vector2(viewPos.x, viewPos.y - offset);m_rectView.offsetMin = viewPos;}/// <summary>/// 滑动列表结束拖拽事件/// </summary>/// <param name="obj"></param>private void OnScrollEndDrag(GameObject obj){m_endScrollHeight = m_scorllView.GetComponent<RectTransform>().localPosition.y;float offset = m_endScrollHeight - m_startScrollHeight;if (Mathf.Abs(offset) >= m_LimitY){m_isOpen = (offset > 0);}ScrollDragAni(m_isOpen);}//动画播放时间private readonly float TWEEN_POS_TIME = 0.2f;/// <summary>/// 滑动条动画/// </summary>/// <param name="isOpen"></param>private void ScrollDragAni(bool isOpen){Vector3 scrollPos = m_scorllView.GetComponent<RectTransform>().localPosition;if (isOpen){DOTween.To(() => scrollPos.y,(v) =>{Vector3 tmpVec = m_scorllView.GetComponent<RectTransform>().localPosition;float offset = v - tmpVec.y;OnPosDrag(offset);}, m_maxHeight, TWEEN_POS_TIME).OnComplete(() => { m_isOpen = true; });}else{DOTween.To(() => scrollPos.y,(v) =>{Vector3 tmpVec = m_scorllView.GetComponent<RectTransform>().localPosition;float offset = v - tmpVec.y;OnPosDrag(offset);},  m_minHeight, TWEEN_POS_TIME).OnComplete(() => { m_isOpen = false; });}}#endregion
}

设置,在滑动列表中,将ViewPort设置成顶端锚点
在这里插入图片描述

相关文章:

  • Java八股文(JVM)
  • 【Go】结构体中Tag标识
  • C语言复习 -- 字符串
  • Qt_day4:2024/3/25
  • NetCore itext7 创建、编辑PDF插入表格、图片、文字(三)
  • R语言使用dietaryindex包计算NHANES数据多种营养指数(2)
  • 自动化组高度件切割计算
  • 为什么Python不适合写游戏?
  • React 应用实现监控可观测性最佳实践
  • 【中间件】docker数据卷
  • 使用Docker搭建YesPlayMusic网易云音乐播放器并发布至公网访问
  • 小米汽车正式发布:开启智能电动新篇章
  • MongoDB内存过高问题分析解决
  • ChatGPT与传统搜索引擎的区别:智能对话与关键词匹配的差异
  • |行业洞察·趋势报告|《2024旅游度假市场简析报告-17页》
  • [ JavaScript ] 数据结构与算法 —— 链表
  • 11111111
  • Android交互
  • C# 免费离线人脸识别 2.0 Demo
  • happypack两次报错的问题
  • JavaScript HTML DOM
  • JavaScript 奇技淫巧
  • JavaScript新鲜事·第5期
  • Mac转Windows的拯救指南
  • React的组件模式
  • 初识 webpack
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 技术发展面试
  • 免费小说阅读小程序
  • 前端技术周刊 2019-02-11 Serverless
  • 微信小程序填坑清单
  • 学习JavaScript数据结构与算法 — 树
  • 《码出高效》学习笔记与书中错误记录
  • Java数据解析之JSON
  • linux 淘宝开源监控工具tsar
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (30)数组元素和与数字和的绝对差
  • (二)学习JVM —— 垃圾回收机制
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (附源码)ssm高校运动会管理系统 毕业设计 020419
  • (五)c52学习之旅-静态数码管
  • (转)一些感悟
  • .NET / MSBuild 扩展编译时什么时候用 BeforeTargets / AfterTargets 什么时候用 DependsOnTargets?
  • .NET Framework与.NET Framework SDK有什么不同?
  • .Net Web窗口页属性
  • .NET 读取 JSON格式的数据
  • .NET 设计一套高性能的弱事件机制
  • .NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化
  • .vue文件怎么使用_我在项目中是这样配置Vue的
  • @requestBody写与不写的情况
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(朱雀组)
  • [ARM]ldr 和 adr 伪指令的区别
  • [Assignment] C++1
  • [BT]小迪安全2023学习笔记(第15天:PHP开发-登录验证)