FancyScrollView通用UI組件

一、簡介

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。

Animators.Update耗時情況

 

SendWillRenderCanvases耗時情況


2、靜止測試
使用同一個示例測試了一下靜止狀態的列表。則動畫更新耗時和UI重建耗時都明顯下降。耗時均值分別爲0.3ms和0ms(<0.05ms)。

Animators.Update耗時情況

 

SendWillRenderCanvases耗時情況

 

五、總結

FancyScrollView可以幫助開發者快速實現靈活複雜的滑動列表動畫,但如果是使用Animator的方式實現,帶來的動畫更新開銷也會偏高一些,更適合在其它CPU壓力不大的場景下使用,且需要注意製作的動畫及動畫狀態機不宜過於複雜。

作者發佈項目時的介紹使用的是日文編寫,爲了方便大家閱讀,UWA開源庫已將其翻譯成中文版本,歡迎大家共同學習:https://lab.uwa4d.com/lab/5bc4219e04617c5805d4d3a1

今天的推薦就到這兒啦,或者它可直接使用,或者它需要您的潤色,或者它啓發了您的思路......

請不要吝嗇您的點贊和轉發,讓我們知道我們在做對的事。當然如果您可以留言給出寶貴的意見,我們會越做越好。


【博物納新】是UWA旨在爲開發者推薦新穎、易用、有趣的開源項目,幫助大家在項目研發之餘發現世界上的熱門項目、前沿技術或者令人驚歎的視覺效果,並探索將其應用到自己項目的可行性。很多時候,我們並不知道自己想要什麼,直到某一天我們遇到了它。

更多精彩內容請關注:lab.uwa4d.com

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章