Asset Storeで販売されている高機能なスクロールビューを実装できるアセットであるEnhanced Scrollerの基本的な使い方を紹介します。
- Enhanced Scroller?
- Hierarchyをセットアップする
- スクリプトを作成する
- セットアップ完了&再生
- セルのサイズは個別に設定できる
- セルのViewは複数設定できる
- セルのデータを更新する
- ループ
- ジャンプ
Unity2018.3.9
Enhanced Scroller?
Enhanced ScrollerはAsset Storeで販売されているアセットです。
スクロールビューのセルのViewをプーリングしてパフォーマンスを向上させたり、
Pull-to-Refreshやページングなどが簡単に実装出来たりと高機能なスクロールビューを実現できます。
これらの機能は独自で実装すると地味に大変だし、
仕様追加に伴いおかしな方向に拡張されがちなので、
最初からライブラリを使ってしまったほうがいいと個人的には思っています。
Hierarchyをセットアップする
Enhanced Scrollerを使うためにまずはHierarchyをセットアップします。
まず適当なuGUIのGameObjectを作って下記の三つのコンポーネントをアタッチします。
- Enhanced Scroller
- Image
- Mask
Inspectorは下記のような感じになります。
Scroll RectはEnhanced Scrollerと一緒に貼られます。
次にその子としてGameObjectを作ります。
名前は何でもいいですが今回はView Container(Temporary)としました。
そしてこのGameObjectをScroll RectのContentに代入します。
そしてこのView Containerの下にセルのViewを作っていきます。
この時、セルのViewは縦横ともStretchにして、大きさは親であるView Containerで調整します。
View Containerはランタイムで使われるものではない(レイアウト用)なので、
セルを調整しやすいサイズに変更してしまって問題ありません。
今回はシンプルなボタンをセルのViewとして作成しました。
このViewはPrefab化しておきます。
最後にControllerという名前のGameObjectをルートオブジェクトとして作っておきます。
スクリプトを作成する
Hierarchyのセットアップが終わったらスクリプトを作っていきます。
Enhanced ScrollerはMVCアーキテクチャを前提として設計されています。
まずセルのデータを保持するためのクラスを作ります。
public class ExampleCellData { public string message; }
次にこのデータを使いセルのViewを作ります。
using EnhancedUI.EnhancedScroller; using System; using UnityEngine; using UnityEngine.UI; public class ExampleCellView : EnhancedScrollerCellView { [SerializeField] private Text _text; [SerializeField] private Button _button; public Action<ExampleCellView> onClick; public void SetData(ExampleCellData data) { _text.text = data.message; } private void Awake() { _button.onClick.AddListener(() => onClick?.Invoke(this)); } }
セルのViewクラスはEnhancedScrollerCellViewを継承する必要があります。
また、先ほど作ったデータをSetDataで渡しています。
このコンポーネントは前節でPrefab化したGameObjectにアタッチしてTextの参照を持たせておきます。
Cell IdentifierにはExample Cell Viewと入力しておきます。
これは、複数の種類のセルを扱うときの識別子となります。
最後にIEnhancedScrollerDelegateを実装したControllerを作ります。
using EnhancedUI.EnhancedScroller; using System.Collections.Generic; using UnityEngine; public class ExampleController : MonoBehaviour, IEnhancedScrollerDelegate { private List<ExampleCellData> _data; [SerializeField] private EnhancedScroller _scroller; [SerializeField] private ExampleCellView _cellViewPrefab; private void Start() { // データを作成 _data = new List<ExampleCellData>(); for (int i = 0; i < 30; i++) { _data.Add(new ExampleCellData { message = "cell " + i }); } _scroller.cellViewVisibilityChanged += view => { if (view.active) { // セルが表示状態になった時の処理 var cellView = (ExampleCellView)view; cellView.SetData(_data[view.dataIndex]); } }; // セルがインスタンス化されたときの処理 _scroller.cellViewInstantiated += (scroller, view) => { var cellView = (ExampleCellView)view; cellView.onClick = x => Debug.Log("Clicked: " + x.dataIndex); }; // Scrollerにデリゲート登録 _scroller.Delegate = this; // ReloadDataをするとビューが更新される _scroller.ReloadData(); } // セルの数を返す public int GetNumberOfCells(EnhancedScroller scroller) { return _data.Count; } // セルのサイズ(縦幅or横幅)を返す public float GetCellViewSize(EnhancedScroller scroller, int dataIndex) { return 50; } // セルのViewを返す public EnhancedScrollerCellView GetCellView(EnhancedScroller scroller, int dataIndex, int cellIndex) { // Scroller.GetCellView()を呼ぶと新規生成orリサイクルを自動的に行ったViewを返してくれる return scroller.GetCellView(_cellViewPrefab); } }
細かい説明はコメントに書きました。
IEnhancedScrollerDelegateを実装し、それをScrollerに登録しています。
このコンポーネントはScrollerにアタッチし、
ScrollerにEnhanced Scrollerを、Cell View PrefabにセルをPrefab化したものを持たせます。
セットアップ完了&再生
以上でセットアップは完了です。
この状態で再生すればスクロールビューが動作していることを確認できます。
セルのサイズは個別に設定できる
ここからは少しだけ応用的な使い方を紹介します。
まず、ControllerのGetCellViewSize()はセルごとに設定できます。
つまりセルのサイズは自由に設定できます。
セルのViewは複数設定できる
またControllerのGetCellView()もセルごとに設定できます。
つまり、複数のPrefabを一つのスクロールビューに使うことができます。
セルのデータを更新する
セルのデータを更新するには、データを書き換えてからEnhancedScroller.RefreshActiveCellViews()を呼びます。
このメソッドは現在表示されている部分だけを処理するので効率が良いです。
ただしセルのサイズの再評価は行わないので、セルサイズも変わるようなデータ更新には対応できません。
そのようなケースでは代わりにEnhancedScroller.ReloadData()を使います。
ループ
Enhanced ScrollerのLoopプロパティにチェックを入れるとループさせることができます。
こんな感じで一番最後の要素の後にまた最初の要素が表示されループするようになります。
ジャンプ
特定の要素にジャンプするにはEnhancedScroller.JumpToDataIndex()を使います。
イージングや秒数も指定出来て非常に便利です。
_scroller.JumpToDataIndex(20, 0, 0, true, EnhancedScroller.TweenType.easeInSine, 1)