Unity Scroll View簡單介紹
最近用到Scroll View組件就簡單記錄一下
Content:(內容)內容元素的引用。
Horizontal:(水平)水平方向拖動。
Vertical:(垂直)垂直方向拖動。
Movement Type:(類型)無限制,彈性,收緊。彈性和收緊模式下將內容限制在滾動矩陣範圍中,彈性模式在達到滾動矩陣的邊緣會反彈。
Elasticity:(彈性)彈性模式下的彈性係數。
Inertia:(慣性)設置慣性後拖動後鬆開內容會繼續滑動。未設置則只有在拖動纔會滑動。
Deceleration Rate:(減速率)設置慣性後,減速率決定元素停止移動的速度。0立即停止,1不會減速。
Scroll Sensitivity:(滾動靈敏度)滾輪滾動事件靈敏度。
Viewport:(視圖端口)層級Viewport引用。
Horizontal Scrollbar:(水平滾動條)對水平滾動條元素引用
Visibility:(能見度)滾動條是否在不需要時自動隱藏,是否還可以擴展。
Spacing:(間隔)滾動條和視口的空間。
1.含有Scroll Rect組件的根節點:Scroll View
2.含有Mask組件的節點:Viewport
3.所有內容的父節點Content,常含有佈局控件
4.滾動條,包括橫向和縱向
節點Scroll View中的組件Rect Transform的Width和Height控制着整個區域大小,組件Scroll Rect的滾動條設置也會影響顯示區域的邊界位置是否完整;
節點Viewport的組件Image中的Image Type屬性會影響顯示的區域;
節點Content的組件Rect Transform的佈局和寬高影響了顯示的區域。
瞭解完組件,我們只需要在Content中將我們的元素放入。爲了自動佈局可以使用自帶的組件
前後添加組件區別。這個組件需要自己去調整尺寸於是我們可以直接用下面這個組件
組件組要作用就是可以自動調整尺寸。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class ScrollViewTest : MonoBehaviour,IBeginDragHandler,IDragHandler,IEndDragHandler
{
private ScrollRect scrollRect;
private RectTransform contentRectTrans;
void Start()
{
scrollRect = GetComponent<ScrollRect>();
//關於RectTransform的探究
contentRectTrans = scrollRect.content;
//當前UI的世界座標
Debug.Log("當前UI的世界座標" + contentRectTrans.position);
//當前UI的局部座標
Debug.Log("當前UI的局部座標" + contentRectTrans.localPosition);
//當前UI的寬度(從左到右的長度)
//Debug.Log("當前UI的寬度"+contentRectTrans.rect.right);
Debug.Log("當前UI的寬度" + contentRectTrans.rect.xMax);
Debug.Log("當前UI的寬度" + contentRectTrans.rect.width);
//當前UI的左座標
Debug.Log("當前ui的左座標" + contentRectTrans.rect.x);
//當前UI的高度
Debug.Log("當前ui的高度" + contentRectTrans.rect.height);
//這裏要注意,他只是當前transform 的x軸的方向
//就像是transform。right自身方向的右邊
Debug.Log("當前ui的左座標" + contentRectTrans.right);
//當前UI底部相對於頂部的相對長度,負數爲向下延展,同理則反
Debug.Log(contentRectTrans.rect.y);
//當前UI的寬高
Debug.Log(contentRectTrans.sizeDelta);
Debug.Log(contentRectTrans.sizeDelta.x);
Debug.Log(contentRectTrans.sizeDelta.y);
//以下爲常用API
//寬度應該是我們想要增加的值
contentRectTrans.sizeDelta = new Vector2(200,178);
//水平滾動位置爲0到1的值,0爲左邊,1爲右邊
scrollRect.horizontalNormalizedPosition = 1;
//拖動事件註冊
scrollRect.onValueChanged.AddListener(PrintValue);
}
private void PrintValue(Vector2 vector2)
{
Debug.Log("傳遞出來的參數值" + vector2);
}
}
直接把代碼掛到scrollview上,可以看到其對應屬性
得注意的是content寬高決定了可拖拽的範圍。如果超過範圍就拖不到最後的元素。
增加一個例子。平時滑動的時候我們需要圖畫在正中間顯示不會偏移,我們就需要對移動的距離進行單位化比例。如果不進行規則化就想下面這樣。
直接上代碼
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using DG.Tweening;
public class SlideCanCoverScrollView : MonoBehaviour,IBeginDragHandler,IEndDragHandler
{
private float contentLength;//容器長度
private float beginMousePostionX;
private float endMousePositionx;
private ScrollRect scrollRect;
private float lastProportion;//上一個位置比例
private RectTransform rect;//獲取scrollview組件
private float scrollviewWidth;//scrollview組件寬度
public int cellLength;//每個單元格長度
public int spacing;//間隙
public int leftOffset;//左偏移量
private float upperLimit;//上限值
private float lowerLimit;//下限值
private float firstItemLength;//移動第一個單元格的距離
private float oneItemLength;//移動一個單元格需要的距離
private float oneItemProportion;//滑動一個單元格所佔比例
public int totalItemNum;//共有幾個單元格
private int currentIndex;//當前單元格索引
private void Awake()
{
rect = GetComponent<RectTransform>();
scrollviewWidth = rect.sizeDelta.x;
scrollRect = GetComponent<ScrollRect>();
contentLength = scrollRect.content.rect.xMax+scrollviewWidth - 2 * leftOffset - cellLength;
Debug.Log("contentLength" + scrollRect.content.rect.xMax);
firstItemLength = cellLength / 2 + leftOffset;
oneItemLength = cellLength + spacing;
oneItemProportion = oneItemLength / contentLength;
upperLimit=1- firstItemLength / contentLength;
lowerLimit = firstItemLength / contentLength;
currentIndex = 1;
scrollRect.horizontalNormalizedPosition = 0;
}
public void OnBeginDrag(PointerEventData eventData)
{
beginMousePostionX = Input.mousePosition.x;
}
public void OnEndDrag(PointerEventData eventData)
{
float offSetX = 0;
endMousePositionx = Input.mousePosition.x;
offSetX = (beginMousePostionX - endMousePositionx)*2;
if (Mathf.Abs(offSetX)>firstItemLength)//執行滑動動作的前提是要大於第一個需要滑動的距離
{
if (offSetX>0)//右滑
{
if (currentIndex>=totalItemNum)
{
return;
}
int moveCount = (int)((offSetX - firstItemLength) / oneItemLength) + 1;//當次可以移動的格子數
currentIndex += moveCount;
if (currentIndex>=totalItemNum)
{
currentIndex = totalItemNum;
}
//當次需要移動的比例:上一次已經存在的單元格位子的比例加上這一次需要去移動的比例
lastProportion += oneItemProportion * moveCount;
if (lastProportion>=upperLimit)
{
lastProportion = 1;
}
}
else//左滑
{
if (currentIndex <=1)
{
return;
}
int moveCount = (int)((offSetX + firstItemLength) / oneItemLength) - 1;//當次可以移動的格子數
currentIndex += moveCount;
if (currentIndex <= 1)
{
currentIndex = 1;
}
//當次需要移動的比例:上一次已經存在的單元格位子的比例加上這一次需要去移動的比例
lastProportion += oneItemProportion * moveCount;
if (lastProportion <= lowerLimit)
{
lastProportion = 0;
}
}
}
DOTween.To(() => scrollRect.horizontalNormalizedPosition, lerpValue => scrollRect.horizontalNormalizedPosition = lerpValue, lastProportion, 0.5f).SetEase(Ease.Linear);
}
}
這樣就實現了自適應。