效果图

用的是UGUI

我先说思路

通过判断元素的位置信息来改变Hierarchy的顺序 实现无限滚动

改变位置的同时也要不断的调整Content的位置防止乱跳

元素锁定就是直接锁死的元素的移动范围 当只有拖动大于一定程度时才会发生改变

然后是面板设置

整体结构是这样子的

需要注意的是Content需要的两个组件

Content的爸爸只需要一个脚本

大小改变曲线(大致就行)

颜色渐变曲线

最后是脚本

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5. using UnityEngine.EventSystems;
  6. using UnityEngine.UI;
  7.  
  8. public class DateControl : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler {
  9.  
  10. public enum ItemType { _year, _month, _day }
  11.  
  12. public ItemType _itemtype;
  13.  
  14. RectTransform conentRect;
  15.  
  16. RectTransform targetRec;
  17.  
  18. Vector3 oldDragPos;
  19.  
  20. Vector3 newDragPos;
  21.  
  22. public AnimationCurve curve_scale;//改变大小曲线
  23. public AnimationCurve curve_color;//渐变效果曲线
  24.  
  25. List<Text> textList = new List<Text>();
  26.  
  27. Button testBtn;
  28.  
  29. float
  30. itemHeight, //子项item的高
  31. contentParentHeight, //Content爸爸的高
  32. itemNum, //子项数量
  33. itemHeight_min, //子项最小发生改变位置
  34. itemHeight_max, //子项最大发生改变位置
  35. conentLimit, //Conent纠正位置
  36. conentSpacing; //子项间隔大小
  37.  
  38. float deltaX, deltaY;
  39.  
  40. [HideInInspector]
  41. public static int _year, _month, _day;
  42.  
  43. [HideInInspector]
  44. int dateItemNum;
  45.  
  46. Color itemColor_hig = new Color32(, , , );
  47.  
  48. void Awake() {
  49. conentRect = transform.FindChild("Content").GetComponent<RectTransform>();
  50. targetRec = transform.parent.FindChild("HighlightTarget").GetComponent<RectTransform>();
  51.  
  52. }
  53.  
  54. void OnEnable() {
  55. ItemList();
  56. }
  57.  
  58. void Start() {
  59. switch (_itemtype) {
  60. case ItemType._year: InstantiateData(, ); break;
  61. case ItemType._month: InstantiateData(, ); break;
  62. case ItemType._day: InstantiateData(, ); break;
  63. }
  64.  
  65. itemNum = transform.FindChild("Content").childCount - ;
  66.  
  67. contentParentHeight = conentRect.parent.GetComponent<RectTransform>().sizeDelta.y;
  68.  
  69. conentSpacing = conentRect.GetComponent<VerticalLayoutGroup>().spacing / ;
  70.  
  71. itemHeight = textList[].rectTransform.sizeDelta.y + conentSpacing;
  72.  
  73. if (itemNum % == ) conentLimit = (itemHeight + ) / ;
  74.  
  75. else conentLimit = ;
  76.  
  77. conentRect.anchoredPosition = new Vector2(conentRect.anchoredPosition.x, conentLimit);
  78.  
  79. deltaX = textList[].GetComponent<RectTransform>().sizeDelta.x;
  80. deltaY = textList[].GetComponent<RectTransform>().sizeDelta.y;
  81.  
  82. Invoke("ItemList", 0.05f);
  83.  
  84. }
  85.  
  86. /// <summary>
  87. /// 生成子项item
  88. /// </summary>
  89. /// <param name="itemNum">子项数量</param>
  90. /// <param name="dat">子项最大值</param>
  91. void InstantiateData(int itemNum, int dat) {
  92. GameObject go;
  93. Text testObj = conentRect.FindChild("Text").GetComponent<Text>();
  94. for (int i = dat - itemNum + ; i <= dat; i++) {
  95. go = Instantiate(testObj.gameObject, conentRect);
  96. go.GetComponent<Text>().text = i.ToString();
  97. go.name = i.ToString();
  98. textList.Add(go.GetComponent<Text>());
  99. ShowItem(true);
  100. }
  101. Destroy(conentRect.FindChild("Text").gameObject);
  102. }
  103.  
  104. /// <summary>
  105. /// 是增加或减少
  106. /// </summary>
  107. /// <param name="isIncreaseOrdecrease"></param>
  108. void ShowItem(bool isIncreaseOrdecrease) {
  109. itemHeight_min = -itemHeight;
  110.  
  111. if (_itemtype == ItemType._day) itemHeight_max = -itemHeight * itemNum - ;
  112. else itemHeight_max = -itemHeight * itemNum;
  113.  
  114. if (isIncreaseOrdecrease) {
  115. foreach (Text rectItem in textList) {
  116. if (rectItem.GetComponent<RectTransform>().anchoredPosition.y > itemHeight_min) {
  117. print("+");
  118. rectItem.transform.SetSiblingIndex((int)itemNum);
  119. }
  120. }
  121. print(itemHeight_min);
  122. } else {
  123. foreach (Text rectItem in textList) {
  124. if (rectItem.GetComponent<RectTransform>().anchoredPosition.y < itemHeight_max) {
  125. print("-");
  126. rectItem.transform.SetSiblingIndex();
  127. }
  128. }
  129. print(itemHeight_max);
  130.  
  131. }
  132. }
  133.  
  134. /// <summary>
  135. /// 渐变效果,改变大小,高亮显示
  136. /// </summary>
  137. void ItemList() {
  138. foreach (Text item in textList) {
  139. float indexA = Mathf.Abs(item.GetComponent<RectTransform>().position.y - targetRec.position.y);
  140. float indexSc_scale = Mathf.Abs(curve_scale.Evaluate(indexA / contentParentHeight));
  141. float indexSc_color = Mathf.Abs(curve_color.Evaluate(indexA / contentParentHeight));
  142. if (indexA < ) {
  143. item.color = itemColor_hig;
  144. switch (_itemtype) {
  145. case ItemType._year: _year = int.Parse(item.text); break;
  146. case ItemType._month: _month = int.Parse(item.text); break;
  147. case ItemType._day: _day = int.Parse(item.text); break;
  148. }
  149. } else item.color = new Color(, , , - indexSc_color);
  150.  
  151. item.GetComponent<RectTransform>().localScale = new Vector3( - indexSc_scale, - indexSc_scale * , - indexSc_scale);
  152. //item.GetComponent<RectTransform>().sizeDelta = new Vector2(deltaX - (deltaX * indexSc), deltaY - (deltaY * indexSc));
  153. }
  154.  
  155. }
  156.  
  157. /// <summary>
  158. /// 获取int类型日期,并转换为指定格式
  159. /// </summary>
  160. /// <returns></returns>
  161. public static string GetDateInfo() { return _year + "-" + _month + "-" + _day; }
  162.  
  163. /// <summary>
  164. /// 纠正Conent位置
  165. /// </summary>
  166. void UpdateEx() {
  167. if (conentRect.anchoredPosition.y > conentLimit) {
  168. ShowItem(true);
  169. conentRect.anchoredPosition = new Vector2(conentRect.anchoredPosition.x, conentRect.anchoredPosition.y - itemHeight);
  170. }
  171. if (conentRect.anchoredPosition.y < conentLimit) {
  172. ShowItem(false);
  173. conentRect.anchoredPosition = new Vector2(conentRect.anchoredPosition.x, conentRect.anchoredPosition.y + itemHeight);
  174. }
  175. }
  176.  
  177. /// <summary>
  178. /// 获取拖拽信息并改变Conent位置
  179. /// </summary>
  180. /// <param name="eventData"></param>
  181. void SetDraggedPosition(PointerEventData eventData) {
  182. if (RectTransformUtility.ScreenPointToWorldPointInRectangle(conentRect, eventData.position, eventData.pressEventCamera, out newDragPos)) {
  183. newDragPos = eventData.position;
  184. if (Mathf.Abs(newDragPos.y - oldDragPos.y) >= itemHeight) {
  185. if (newDragPos.y > oldDragPos.y) {
  186. conentRect.anchoredPosition = new Vector2(conentRect.anchoredPosition.x, conentRect.anchoredPosition.y + itemHeight);
  187. oldDragPos += new Vector3(, itemHeight, );
  188. ItemList();
  189. } else {
  190. conentRect.anchoredPosition = new Vector2(conentRect.anchoredPosition.x, conentRect.anchoredPosition.y - itemHeight);
  191. oldDragPos -= new Vector3(, itemHeight, );
  192. ItemList();
  193. }
  194. }
  195. }
  196. }
  197.  
  198. /// <summary>
  199. /// 当开始拖拽
  200. /// </summary>
  201. /// <param name="eventData"></param>
  202. public void OnBeginDrag(PointerEventData eventData) {
  203. oldDragPos = eventData.position;
  204. }
  205.  
  206. public void OnDrag(PointerEventData eventData) {
  207. SetDraggedPosition(eventData);
  208. UpdateEx();
  209. }
  210.  
  211. public void OnEndDrag(PointerEventData eventData) {
  212. SetDraggedPosition(eventData);
  213. UpdateEx();
  214. }
  215. }

照着来的话基本没什么问题

因为赶时间所以很多地方写的简单粗暴请谅解

如果调整元素大小或者间隙大小 需要改变itemHeight_min 和 itemHeight_max 的值

他们分别为

itemHeight_min

itemHeight_max 

也就是元素的最顶层和最底层的Y值

以上就是年月日选择器的具体步骤

Unity3d—做一个年月日选择器(Scroll Rect拖动效果优化)— 无限滚动 + 锁定元素的更多相关文章

  1. 用Django做一个省份选择器

    做一个省份选择器 使用django做后端, mysql数据库, jQuery 列出结构主要的文件, 其它配置比较简单 models.py 因为所有数据的结构基本一致, 把所有省份, 市和区全部存储一张 ...

  2. 关于longPressGesture做一个长按连加的效果(原创)

    关于longPressGesture做一个长按连加的效果 解释一下什么意思呢?就是一个button长按之后其数字的一直累加.朋友们可能看起来很简单,无非就是加一个长按手势(longPressGestu ...

  3. WPF 自己做一个颜色选择器

    程序开发过程中,经常会遇到需要支持动态配置主题颜色的问题,通常,一个程序会有多种不同的颜色风格主题供选 有时候,更细致一些的地方,会需要支持自己配置颜色,这样我们就需要一个颜色选择器啦,下面是我自己开 ...

  4. 做一个360度看车的效果玩玩(web)

    前几天在 Lexus 官网看到有这样的一个效果:http://www.lexus.com.cn/models/es/360 于是顺手打开控制台看了下他们是怎么做的,发现使用的技术还是比较简单的,通过背 ...

  5. css3加js做一个简单的3D行星运转效果

    前几天在园子里看到一篇关于CSS3D行星运转的文章,原文在这里,感觉这个效果也太酷炫了,于是自己也就心血来潮的来尝试的做了一下.因为懒得去用什么插件了,于是就原生的JS写,效果有点粗超,还有一些地方处 ...

  6. 做一个阅读管理APP

    背景 由于最近在看的书有点多,所以一直想找一个能够管理阅读进度的书(鄙人记性不是很好,两天不看就忘了)可惜Android平台上一直找不到合适的APP: 有没有读书进度管理的网站或软件啊? 有没有记录读 ...

  7. Infinite Scroll - jQuery & WP 无限滚动插件

    无限滚动(Infinite Scroll)也称为自动分页.滚动分页和无限分页.常用在图片.文章或其它列表形式的网页中,用来在滚动网页的时候自动加载下一页的内容.Infinite Scroll  这款  ...

  8. 用Jquery做一个时间日期选择器

    今天我们就用Jquery做一个时间日期选择器,当打开网页时,文本框里面显示的是当前的日期,点击文本框可以出现年.月.日的下拉菜单,并且可以选择,会根据年份的选择判断是否是闰年,从而改变二月的天数,闰年 ...

  9. 【跟我一起学Unity3D】做一个2D的90坦克大战之AI系统

    对于AI,我的初始想法非常easy,首先他要能动,而且是在地图里面动. 懂得撞墙后转弯,然后懂得射击,其它的没有了,基于这个想法,我首先创建了一个MyTank类,用于管理玩家的坦克的活动,然后创建AI ...

随机推荐

  1. Java中Json解析

    首先准备一个JSON格式的字符串 * String JsonStr = "{object:{persons:" + "[{name:'呵呵',image:'http:// ...

  2. 推送一个已有的代码到新的 gerrit 服务器

    1.指定项目代码库中迭代列出全部ProductList(.git)到pro.log文件中 repo forall -c 'echo $REPO_PROJECT' | tee pro.log pro.l ...

  3. Supervisor: A Process Control System

    Supervisor: 进程控制系统 概述:Supervisor是一个 Client/Server模式的系统,允许用户在类unix操作系统上监视和控制多个进程,或者可以说是多个程序. 它与launch ...

  4. poj1159二维树状数组

    Suppose that the fourth generation mobile phone base stations in the Tampere area operate as follows ...

  5. jdbc连接数据库工具包模板

    jdbc连接数据库操作 jdbc连接数据库模板,收藏可做模板使用(小型工程,一般大工程都会用框架,c3p0等连接,不考虑此种方法!). 配置文件的使用(使用配置文件可以使我们后期的修改更加方便,当然, ...

  6. 关于IT创业和反思

    2016年8月的某一天本是世上平凡的一天,对于我而言却并不平凡. 这一天,我离开了待了近四年的创业公司.从它成立前的筹备开始,伴随着它的起起伏伏到完成C轮融资,从来没想过以这种方式离开,然而人生总是充 ...

  7. 每天一道Java题[2]

    问题 可以直接根据hashCode()方法产生的值判断两个对象是否相等吗? 解答 不能!根据Wikipedia(https://en.wikipedia.org/wiki/Java_hashCode( ...

  8. 如何在Eclipse下查看JDK源代码

    设置: 1.点 "窗口"-> "首选项" -> "Java" -> "已安装的JRE" 2.此时&qu ...

  9. IE6.0升级的两种通用代码

    随着W3C组织开始针对新的Web标准提案日期的到来,HTML5以及CSS3的新时代即将到来,同时微软的Win8以及IE10的出现也带给了这个世界奇妙的结构. 微软早在不再给WinXP做技术支持时,IE ...

  10. CoreOS, Kubernetes, etcd

    CoreOS CoreOS Container Linux is the leading container operating system, designed to be managed and ...