using UnityEngine; using UnityEngine.EventSystems; using System.Collections; using EnhancedUI; using EnhancedUI.EnhancedScroller; namespace EnhancedScrollerDemos.PullDownRefresh { /// /// This example shows one way you can implement a pull down to refresh feature. /// /// When you are near the top of the scroller, the instructions to pull down appear. /// As you drag the scroller down, the release to refresh instructions appear. /// When you release, new data is inserted into the dataset and the scroller is reloaded. /// /// Note that this example requires the controller to be on the same game object /// as the EnhancedScroller component for the OnBeginDrag and OnEndDrag functions to work. /// public class Controller : MonoBehaviour, IEnhancedScrollerDelegate, IBeginDragHandler, IEndDragHandler { /// /// Internal representation of our data. Note that the scroller will never see /// this, so it separates the data from the layout using MVC principles. /// private SmallList _data; /// /// Whether the scroller is being dragged /// private bool _dragging = false; /// /// Whether we should refresh after releasing the drag /// private bool _pullToRefresh = false; /// /// This is our scroller we will be a delegate for /// public EnhancedScroller scroller; /// /// This will be the prefab of each cell in our scroller. Note that you can use more /// than one kind of cell, but this example just has the one type. /// public EnhancedScrollerCellView cellViewPrefab; /// /// The higher the number here, the more we have to pull down to refresh /// public float pullDownThreshold; /// /// Some text to show that the user can pull down to refresh. /// Only shows up when near the top of the scroller in this example. /// public UnityEngine.UI.Text pullDownToRefreshText; /// /// Some text to show that the user can release to refresh. /// public UnityEngine.UI.Text releaseToRefreshText; /// /// Be sure to set up your references to the scroller after the Awake function. The /// scroller does some internal configuration in its own Awake function. If you need to /// do this in the Awake function, you can set up the script order through the Unity editor. /// In this case, be sure to set the EnhancedScroller's script before your delegate. /// /// In this example, we are calling our initializations in the delegate's Start function, /// but it could have been done later, perhaps in the Update function. /// void Start() { // set the application frame rate. // this improves smoothness on some devices Application.targetFrameRate = 60; // tell the scroller that this script will be its delegate scroller.Delegate = this; // tell our controller to monitor the scroller's scrolled event. scroller.scrollerScrolled = ScrollerScrolled; // load in a large set of data LoadLargeData(); } /// /// Populates the data with a lot of records /// private void LoadLargeData() { // set up some simple data _data = new SmallList(); for (var i = 0; i < 100; i++) _data.Add(new Data() { someText = "Cell Data Index " + i.ToString() }); // tell the scroller to reload now that we have the data scroller.ReloadData(); } #region EnhancedScroller Handlers /// /// This tells the scroller the number of cells that should have room allocated. This should be the length of your data array. /// /// The scroller that is requesting the data size /// The number of cells public int GetNumberOfCells(EnhancedScroller scroller) { // in this example, we just pass the number of our data elements return _data.Count; } /// /// This tells the scroller what the size of a given cell will be. Cells can be any size and do not have /// to be uniform. For vertical scrollers the cell size will be the height. For horizontal scrollers the /// cell size will be the width. /// /// The scroller requesting the cell size /// The index of the data that the scroller is requesting /// The size of the cell public float GetCellViewSize(EnhancedScroller scroller, int dataIndex) { // in this example, even numbered cells are 30 pixels tall, odd numbered cells are 100 pixels tall return (dataIndex % 2 == 0 ? 30f : 100f); } /// /// Gets the cell to be displayed. You can have numerous cell types, allowing variety in your list. /// Some examples of this would be headers, footers, and other grouping cells. /// /// The scroller requesting the cell /// The index of the data that the scroller is requesting /// The index of the list. This will likely be different from the dataIndex if the scroller is looping /// The cell for the scroller to use public EnhancedScrollerCellView GetCellView(EnhancedScroller scroller, int dataIndex, int cellIndex) { // first, we get a cell from the scroller by passing a prefab. // if the scroller finds one it can recycle it will do so, otherwise // it will create a new cell. CellView cellView = scroller.GetCellView(cellViewPrefab) as CellView; // set the name of the game object to the cell's data index. // this is optional, but it helps up debug the objects in // the scene hierarchy. cellView.name = "Cell " + dataIndex.ToString(); // in this example, we just pass the data to our cell's view which will update its UI cellView.SetData(_data[dataIndex]); // return the cell to the scroller return cellView; } #endregion /// /// This delegate will fire when the scroller is scrolled /// /// /// /// private void ScrollerScrolled(EnhancedScroller scroller, Vector2 val, float scrollPosition) { var scrollMoved = (scroller.ScrollRect.content.anchoredPosition.y <= -pullDownThreshold); if (_dragging && scrollMoved) { // we are dragging and the scroll position is beyond the scroll threshold. // we should flag that a refresh is needed when the dragging is released. _pullToRefresh = true; // show the release text if the scroller is down beyond the threshold releaseToRefreshText.gameObject.SetActive(true); } // show the pull to refresh text if the scroller position is at the top pullDownToRefreshText.gameObject.SetActive(scrollPosition <= 0); } /// /// Fired by the ScrollRect /// /// public void OnBeginDrag(PointerEventData data) { // we are now dragging. // we flag this so that refreshing won't occur if the scroller // is scrolling due to inertia. // the user must drag manually in this example. _dragging = true; } /// /// Fired by the ScrollRect /// /// public void OnEndDrag(PointerEventData data) { // no longer dragging _dragging = false; if (_pullToRefresh) { // we reached the scroll pull down threshold, so now we insert new data for (var i = 0; i < 3; i++) { _data.Insert(new Data() { someText = "Brand New Data " + i.ToString() + "!!!" }, 0); } // reload the scroller to show the new data scroller.ReloadData(); // take off the refresh now that it is handled _pullToRefresh = false; // hide the release text if the scroller is down beyond the threshold releaseToRefreshText.gameObject.SetActive(false); } } } }