一、簡介
FancyScrollView是一個可以實現複雜靈活動畫效果的通用UI滑動列表組件,可以幫助開發者快速實現表現力豐富的UI滑動列表。
開源庫鏈接:https://lab.uwa4d.com/lab/5bc4219e04617c5805d4d3a1
二、創建一個FancyScrollView
以示例項目中最基礎的第一個例子爲例,來看一下如何使用FancyScrollView實現一個動畫滑動列表。
1、創建一個ItemData類,用於存放每個單元中所需的數據。
public class ItemData
{
public string Message { get; }
public ItemData(string message)
{
Message = message;
}
}
2、創建一個Cell類,繼承自FancyCell。其中有兩個主要函數,UpdateContent用於刷新UI上對應ItemData中的數據內容,UpdatePosition用於控制每個Cell的滑動效果,包括位置、動畫等。在Example01中,使用了Animator來控制動畫。
public class MyCell : FancyCell<ItemData>
{
[SerializeField] Animator animator = default;
[SerializeField] Text message = default;
public override void UpdateContent(ItemData itemData)
{
message.text = itemData.Message;
}
public override void UpdatePosition(float position)
{
// position 是 0.0 ~ 1.0 之間的值
// 基於position可以自由控制Scroll的外觀
if (animator.isActiveAndEnabled)
{
animator.Play(AnimatorHash.Scroll, -1, position);
}
animator.speed = 0;
}
}
3、創建一個ScrollView類,繼承自FancyScrollView。
public class MyScrollView : FancyScrollView<ItemData>
{
[SerializeField] Scroller scroller = default;
[SerializeField] GameObject cellPrefab = default;
protected override GameObject CellPrefab => cellPrefab;
void Start()
{
scroller.OnValueChanged(base.UpdatePosition);
}
public void UpdateData(IList<ItemData> items)
{
base.UpdateContents(items);
scroller.SetTotalCount(items.Count);
}
}
4、創建一個Example01,用於初始化列表數據。
public class Example01 : MonoBehaviour
{
[SerializeField] MyScrollView myScrollView = default;
void Start()
{
var items = Enumerable.Range(0, 20)
.Select(i => new ItemData($"Cell {i}"))
.ToArray();
myScrollView.UpdateData(items);
}
}
5、創建一個Cell Prefab,爲它製作一個好看的動畫效果,並創建制作好對應的AnimatorController。
6、組裝好這些GameObject後,即可得到一個FancyScrollView效果啦。
三、其它功能及應用
1、無限循環
如果希望實現頭尾相接的循環列表,只需要設置兩個選項:勾選FancyScrollView的“Loop”,並將Scroller的Movement Type設定爲Unrestricted即可。
2、捕捉(Snap)
啓用Snap之後,在滑動快結束時會定位到最近的一個單元,而不會停留在中間狀態。這也是滑動列表非常常用的功能。同時還可以調整這裏定位的速度、時長、EasingType等參數。
3、結合Shader製作列表背景
在示例4和示例5中,展示瞭如何使用Shader製作出表現力更豐富的滑動列表。這裏給出的兩個例子分別是Metaball和Voronoi效果的應用。
在Metaball.hlsl中,可以找到Shader實現的核心方法。
float4 metaball(float2 st)
{
float scale = 4600;
float d = 0;
[unroll]
for (int i = 0; i < DATA_COUNT; i++)
{
d += f(st - _CellState[i].xy) * _CellState[i].w;
}
d *= scale;
d = abs(d - 0.5);
float3 color = 1;
color = lerp(color, float3(0.16, 0.07, 0.31), smoothstep(d - 0.04, d - 0.04 + 0.002, 0));
color = lerp(color, float3(0.16, 0.80, 0.80), smoothstep(d - 0.02, d - 0.02 + 0.002, 0));
return float4(color, 1)
}
其中_CellState爲ScrollView中的Cell數據集合。xy對應的是每個Cell的位置position數據,w對應的是每個cell的縮放scale數據。
4、ScrollRect和GridView
除了常規的滑動列表外,FancyScrollView還提供了行列類的滑動列表,且在示例工程中,提供瞭如果修改Cell單元間距、頂距等配置方式。但這兩種ScrollView不支持無限循環和捕捉功能。
四、性能測評
效果雖好,但由於這裏面每個cell都用到一個Animator,在性能上也是有不少開銷的。博物納新慣例,使用UWA GOT在紅米4X上測試了一下最基礎示例的性能開銷。
1、滑動測試
使用基礎示例測試了一下持續滑動列表的情況。發現動畫更新耗時和UI重建的開銷在列表滑動時都比較高,是兩個主要耗時函數,其耗時均值分別達到1.9ms和1.6ms。
2、靜止測試
使用同一個示例測試了一下靜止狀態的列表。則動畫更新耗時和UI重建耗時都明顯下降。耗時均值分別爲0.3ms和0ms(<0.05ms)。
五、總結
FancyScrollView可以幫助開發者快速實現靈活複雜的滑動列表動畫,但如果是使用Animator的方式實現,帶來的動畫更新開銷也會偏高一些,更適合在其它CPU壓力不大的場景下使用,且需要注意製作的動畫及動畫狀態機不宜過於複雜。
作者發佈項目時的介紹使用的是日文編寫,爲了方便大家閱讀,UWA開源庫已將其翻譯成中文版本,歡迎大家共同學習:https://lab.uwa4d.com/lab/5bc4219e04617c5805d4d3a1
今天的推薦就到這兒啦,或者它可直接使用,或者它需要您的潤色,或者它啓發了您的思路......
請不要吝嗇您的點贊和轉發,讓我們知道我們在做對的事。當然如果您可以留言給出寶貴的意見,我們會越做越好。
【博物納新】是UWA旨在爲開發者推薦新穎、易用、有趣的開源項目,幫助大家在項目研發之餘發現世界上的熱門項目、前沿技術或者令人驚歎的視覺效果,並探索將其應用到自己項目的可行性。很多時候,我們並不知道自己想要什麼,直到某一天我們遇到了它。
更多精彩內容請關注:lab.uwa4d.com