UGUI无限滚动列表
正在忙别的东东,突然公司来了个需求,要加个什么无限滚动列表需求,再三确认,没错他就要这个(心想这玩意都烂大街,分分钟给你复制粘贴一个),然后就找啊找,找了一堆,没有找到正好对应需求的,然后找了个靠近需求的源码,改啊改,改啊改..... 我吐了!!!
思路:
1.无限滚动,Object肯定得重复利用 (位置循环)
2.保证循序正确,如果当前界面显示3个image,那我就生成9个image,canvas左边三个,右边三个,一摸一样的(因为我就三个数据,如果要是做成游戏那种无限滚动用来显示不用数据的,需要加个数据索引的集合,实时更新)
3.UGUI自带的scroll view 层级太多了,层级之间的引用看的头大(哈哈哈,底子不扎实)
制作:
1.ScrollDrog :继承拖拽接口,点击接口 (位置更新)
2.ChildLayout:只是为了子物体的布局,都是自己计算,现在只是定义了Item的大小和间距,还有其他的一些可以拓展
要点:初始化的时候记录所有子物体的位置,然后移动的时候检测有没有物体的位置大于最右边或者小于最左边的位置,然后更新位置
我是为了debug方便,给每个Item下面的text记录目标位置的索引,(这个是位置的索引,不是数据的索引,如果有需要的话自己加)
,Ondrag接口:这个只有在鼠标点下之后,有PointerEventData.delta(偏移)的时候调用
下面是代码:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using DG.Tweening;
public class ScrollDrog : UIBehaviour, IPointerUpHandler, IPointerDownHandler, IBeginDragHandler, IEndDragHandler, IDragHandler,IInitializePotentialDragHandler
{
public enum DropDirection {
Horizatal,
Verticle,
}
Vector2 delta;
public DropDirection dropDirection;
ChildLayout childLayout;
public void OnInitializePotentialDrag(PointerEventData eventData)
{
eventData.useDragThreshold = true;
}
public Action OnCustomStartDrop;
public Action OnCustomEndDrop;
public void OnBeginDrag(PointerEventData eventData)
{
}
public float speed;
public void OnDrag(PointerEventData eventData)
{
if (dropDirection== DropDirection.Horizatal)
{
//查找所有子物体移动
delta = eventData.delta;
delta.y = 0;
for (int i = 0; i < transform.childCount; i++)
{
transform.GetChild(i).GetComponent<RectTransform>().anchoredPosition += delta.normalized*Time.deltaTime*speed;
}
}
//跟新位置
Vector2 posMin = primitivePostion[0];
Vector2 posMax = primitivePostion[primitivePostion.Count - 1];
for (int i = 0; i < transform.childCount; i++)
{
RectTransform rectTrans = transform.GetChild(i).GetComponent<RectTransform>();
Vector2 pos = rectTrans.anchoredPosition;
if (pos.x< posMin.x &&Mathf.Abs(pos.x - posMin.x) > childLayout.cellSize.x)
{
transform.GetChild(i).GetComponent<RectTransform>().anchoredPosition = transform.GetChild(i).GetComponent<RectTransform>().anchoredPosition + new Vector2(transform.childCount * (childLayout.cellSize.x + childLayout.cellPadding.x), 0);
}
if (pos.x > posMax.x && Mathf.Abs(pos.x - posMax.x) > childLayout.cellSize.x)
{
transform.GetChild(i).GetComponent<RectTransform>().anchoredPosition = transform.GetChild(i).GetComponent<RectTransform>().anchoredPosition - new Vector2(transform.childCount * (childLayout.cellSize.x + childLayout.cellPadding.x), 0);
}
}
}
public void OnEndDrag(PointerEventData eventData)
{
for (int i = 0; i < transform.childCount; i++)
{
RectTransform rectTrans = transform.GetChild(i).GetComponent<RectTransform>();
string index = transform.GetChild(i).Find("Text").GetComponent<Text>().text;
//rectTrans.anchoredPosition = primitivePostion[int.Parse(index)];
//rectTrans.anchoredPosition =Vector2.SmoothDamp() primitivePostion[int.Parse(index)];
rectTrans.DOAnchorPos(primitivePostion[int.Parse(index)], 0.3f).SetEase(Ease.OutBounce).onComplete += () =>
{
rectTrans.anchoredPosition = primitivePostion[int.Parse(index)];
Debug.Log("isDoTweenAll.isDoTweenAll: " + i);
};
}
}
List<Vector2> primitivePostion;
protected override void Start()
{
base.Start();
childLayout = GetComponent<ChildLayout>();
childLayout.enabled = false;
primitivePostion = new List<Vector2>();
for (int i = 0; i < transform.childCount; i++)
{
primitivePostion.Add(transform.GetChild(i).GetComponent<RectTransform>().anchoredPosition);
transform.GetChild(i).Find("Text").GetComponent<Text>().text = i+"";
transform.GetChild(i).gameObject.name = i + "";
}
}
private void Update()
{
for (int i = 0; i < transform.childCount; i++)
{
RectTransform rectTrans = transform.GetChild(i).GetComponent<RectTransform>();
Vector2 pos = rectTrans.anchoredPosition;
int index = GetNearPos(pos);
transform.GetChild(i).Find("Text").GetComponent<Text>().text = index + "";
}
for (int i = 0; i < transform.childCount; i++)
{
RectTransform rectTrans = transform.GetChild(i).GetComponent<RectTransform>();
if (Mathf.Abs(rectTrans.anchoredPosition.x)<(childLayout.cellSize.x+childLayout.cellPadding.x))
{
float currentOffset= Mathf.Abs(rectTrans.anchoredPosition.x) - (childLayout.cellSize.x + childLayout.cellPadding.x);
float sFoctor= currentOffset / (childLayout.cellSize.x + childLayout.cellPadding.x);
float offset= (1- sFoctor);
rectTrans.localScale = Vector3.one* (offset);
}
else
{
rectTrans.localScale = Vector3.one;
}
Vector2 pos = rectTrans.anchoredPosition;
int index = GetNearPos(pos);
transform.GetChild(i).Find("Text").GetComponent<Text>().text = index + "";
}
}
float scale = 2;
/// <summary>
/// targetPos
/// </summary>
/// <param name="currentPos"></param>
/// <returns></returns>
int GetNearPos(Vector2 currentPos) {
int index = 0;
float xOffset= Mathf.Abs(primitivePostion[0].x - currentPos.x);
for (int i = 0; i < primitivePostion.Count; i++)
{
if (Mathf.Abs(primitivePostion[i].x-currentPos.x)<xOffset)
{
index = i;
xOffset = Mathf.Abs(primitivePostion[i].x - currentPos.x);
}
}
return index;
}
public void OnPointerDown(PointerEventData eventData)
{
if (OnCustomStartDrop != null)
{
OnCustomStartDrop();
}
}
public void OnPointerUp(PointerEventData eventData)
{
if (OnCustomEndDrop != null)
{
OnCustomEndDrop();
}
}
}
//=======================================================================================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class ChildLayout : MonoBehaviour
{
// Start is called before the first frame update
public enum StartPosition {
Middle,
Left,
Right,
}
public StartPosition startPosition;
[Header("格子的大小")]
public Vector2 cellSize;
[Header("格子的间距")]
public Vector2 cellPadding;
public List<Vector2> p;
// Update is called once per frame
void Update()
{
if (Application.isPlaying)
{
return;
}
switch (startPosition)
{
case StartPosition.Middle:
List<Vector2> p = LayoutPositon();
for (int i = 0; i < transform.childCount; i++)
{
transform.GetChild(i).GetComponent<RectTransform>().sizeDelta = cellSize; //delta;
transform.GetChild(i).GetComponent<RectTransform>().anchoredPosition = p[i];
}
break;
case StartPosition.Left:
break;
case StartPosition.Right:
break;
default:
break;
}
}
List<Vector2> LayoutPositon() {
List<Vector2> pos = new List<Vector2>();
for (int i = 0; i < transform.childCount; i++)
{
pos.Add(new Vector2(i * (cellSize.x + cellPadding.x), transform.GetChild(i).GetComponent<RectTransform>().anchoredPosition.y));
}
//计算整体偏移
int offset = transform.childCount / 2;
for (int i = 0; i < pos.Count; i++)
{
Vector2 v2 = pos[i];
v2.x -= offset * (cellSize.x + cellPadding.x);
pos[i] = v2;
}
return pos;
}
}
ScrollViewDemo.rar-Unity3D文档类资源-CSDN下载
不多说了,研究shader去了
UGUI无限滚动列表相关推荐
- Unity3D 无限滚动列表
在游戏开发的过程中,会经常用到无限滚动列表做一些界面的展示,像排行榜,房间列表,好友列表,装备列表等等,GitHub有个非常好用的无限滚动列表,这个滚动列表是基于UGUI的,所以需要创建一个UGUI的 ...
- 如何使用 React 编写无限滚动列表
英文 | https://javascript.plainenglish.io/how-to-write-an-infinite-scroll-list-with-react-6565c775aef6 ...
- 微信小程序实现无限滚动列表
实现方式是利用小程序原声组件swiper,方向设置为纵向 :vertical='true'设置同时显示的滑块数量:display-multiple-items='4'设置自动轮播:autoplay:' ...
- Unity UGUI无限列表(Infinite List)
更新日期:2020年10月16日. Github源码:[点我获取源码] 索引 InfiniteList 使用 创建InfiniteListScrollRect InfiniteListScrollRe ...
- 深入Flutter(四) Infinite scrolling -- 无限滚动
文章系列 深入Flutter(一) 积极推进"组合"方式 深入Flutter(二) 线性时间复杂度的 build 和 layout 深入Flutter(三) Element树和Re ...
- 使用 GraphQL 无限滚动
在构建为用户提供一长串信息的应用程序时,例如新闻提要.论坛中的帖子或聊天应用程序中的消息,我们的目标是向用户显示合理数量的信息. 用户开始滚动浏览初始列表后,Web 客户端应立即加载更多内容以继续向用 ...
- 微信小程序 - 新闻动态 / 公告上下滚动列表(上下循环滚动,无限上下自动滚动列表)
前言 本文实现了 无限上下自动滚动列表 组件,常见于新闻动态列表.公告等场景,可直接调用. 您可以自定义滚动间隔与显示多少个列表, 另外点击每项会触发事件,可用于跳转到详情页. 代码干净整洁,注释详细 ...
- CSS3实现列表无限滚动/轮播
使用CSS3实现列表的无限滚动/轮播 效果预览 思路 将当前列表滚动至最后一项的末尾,然后瞬间切换回第一项 问题点 用什么方式实现无限轮播 这个问题就是列表滚动到最后时底部会留白(有多余空间)如何处理 ...
- 微信小程序 滚动列表(无限滚动)
效果图1.0 实现方式是利用小程序原声组件swiper,方向设置为纵向 :vertical='true'设置同时显示的滑块数量:display-multiple-items='4'设置自动轮播:aut ...
最新文章
- 机器学习与数据科学 基于R的统计学习方法(基础部分)
- 一篇与众不同的 String、StringBuilder 和 StringBuffer 详解
- 从起源到具体算法,这篇深度学习综述论文送给你
- 装系统w7、ubuntu、centos等系统(一)
- 机器学习 不均衡数据的处理方法
- 在asp.net中如何用javascript读取本地Xml中的数据到网页中的文本框?
- mysql弄丢初始密码_MySql密码丢失
- Android之在ubuntu上用aapt查看apk的名字以及相关信息
- 【OS学习笔记】三 计算机的启动过程
- Netflix 混沌工程手册 Part 3:实践方法
- web后端语言_web前端学习路线图_快速入门web前端学习路线图
- JAVAWeb开发之Servlet-18.Servlet共享变量与变量的作用域
- pandas.DataFrame API
- fatal: The remote end hung up unexpectedly
- word的表格取消边框后还有虚线怎么办
- 新零售时代,异业联盟怎么做?
- Nvidia 的Kal-El Tegra将五核合一
- 如何读取STL文件?
- 普通本科,开发一周年纪念日—-赠给自己的礼物
- 离群值(异常值)处理