Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

New UI Widgets

Discussion in 'Assets and Asset Store' started by ilih, Feb 11, 2015.

  1. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    Replace UpdateView() in ListViewCustom.cs
    Code (CSharp):
    1.         protected void UpdateView()
    2.         {
    3.             RemoveCallbacks();
    4.  
    5.             if ((CanOptimize()) && (DataSource.Count > 0))
    6.             {
    7.                 visibleItems = (maxVisibleItems < DataSource.Count) ? maxVisibleItems : DataSource.Count;
    8.             }
    9.             else
    10.             {
    11.                 visibleItems = DataSource.Count;
    12.             }
    13.  
    14.             if (CanOptimize())
    15.             {
    16.                 topHiddenItems = GetFirstVisibleIndex();
    17.                 if (topHiddenItems > (DataSource.Count - 1))
    18.                 {
    19.                     topHiddenItems = Mathf.Max(0, DataSource.Count - 2);
    20.                 }
    21.                 if ((topHiddenItems + visibleItems) > DataSource.Count)
    22.                 {
    23.                     visibleItems = DataSource.Count - topHiddenItems;
    24.                 }
    25.                 bottomHiddenItems = Mathf.Max(0, DataSource.Count - visibleItems - topHiddenItems);
    26.             }
    27.             else
    28.             {
    29.                 topHiddenItems = 0;
    30.                 bottomHiddenItems = DataSource.Count() - visibleItems;
    31.             }
    32.  
    33.             UpdateComponentsCount();
    34.            
    35.             base.Items = components.ConvertAll(x => x as ListViewItem);
    36.  
    37.             var indicies = Enumerable.Range(topHiddenItems, visibleItems).ToArray();
    38.             components.ForEach((x, i) => {
    39.                 x.Index = indicies[i];
    40.                 x.transform.SetAsLastSibling();
    41.                 SetData(x, DataSource[indicies[i]]);
    42.                 Coloring(x as ListViewItem);
    43.             });
    44.  
    45.             AddCallbacks();
    46.  
    47.             if (layout)
    48.             {
    49.                 SetFiller();
    50.                 layout.UpdateLayout();
    51.             }
    52.         }
     
  2. sebastien-barry

    sebastien-barry

    Joined:
    Dec 18, 2013
    Posts:
    53
    Hi,
    Ok, it works, but now if I remove an item, when I scroll Up and down the tileview, items are shifting.

    Another question, will you include all those correction in next release ?
     
  3. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    Fix:
    1. ListViewCustom.cs, add following functions
      Code (CSharp):
      1.         protected virtual float GetItemPosition(int index)
      2.         {
      3.             return index * GetItemSize();
      4.         }
      5.        
      6.         protected virtual float GetItemPositionBottom(int index)
      7.         {
      8.             var margin = (IsHorizontal()) ? layout.GetMarginLeft() : layout.GetMarginTop();
      9.             return GetItemPosition(index) + GetItemSize() - GetItemSpacing() + margin - GetScrollSize();
      10.         }
    2. ListViewCustom.cs, add at the end of UpdateView()
      Code (CSharp):
      1.             if (ScrollRect!=null)
      2.             {
      3.                 var item_ends = (DataSource.Count==0) ? 0f : GetItemPositionBottom(DataSource.Count - 1);
      4.                
      5.                 if (GetScrollValue() > item_ends)
      6.                 {
      7.                     SetScrollValue(item_ends);
      8.                 }
      9.             }
    3. TileView.cs, add function
      Code (CSharp):
      1.         protected override float GetItemPosition(int index)
      2.         {
      3.             var block_index = Mathf.FloorToInt((float)index / (float)ItemsPerBlock());
      4.             return block_index * GetItemSize();
      5.         }

    Yes.
     
  4. sebastien-barry

    sebastien-barry

    Joined:
    Dec 18, 2013
    Posts:
    53
    The problem is still present and now I get a stackoverflow exception when I Clear or remove tileviewItems.
    My Treeviews also have strange scroll behaviour whith those new lines of codes.

    Another point, I have this problem with Tileview and listview (no test with other components) :
    I cannot clear and Add items in the same function call.

    The only way I found to clear and bind new data is the following :
    public void ClearAndBindTileView()
    {
    myTIleView.Clear();
    StartCoroutine(BindAfterClear());
    }

    IEnumerator BindAfterClear()
    {
    yield return new WaitForEndOfFrame();
    // Add new items to the TIleView
    }
     
    Last edited: Nov 16, 2015
  5. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    Sorry, I had to check better.
    Fix:
    • ListViewCustom.cs, replace line in UpdateView()
      old line:
      Code (CSharp):
      1.                 var item_ends = (DataSource.Count==0) ? 0f : GetItemPositionBottom(DataSource.Count - 1);
      new line:
      Code (CSharp):
      1. var item_ends = (DataSource.Count==0) ? 0f : Mathf.Max(0f, GetItemPositionBottom(DataSource.Count - 1));
    • TileView.cs, replace line in ScrollUpdate()
      old line:
      Code (CSharp):
      1.             visibleItems = maxVisibleItems;
      new line:
      Code (CSharp):
      1.             if ((CanOptimize()) && (DataSource.Count > 0))
      2.             {
      3.                 visibleItems = (maxVisibleItems < DataSource.Count) ? maxVisibleItems : DataSource.Count;
      4.             }
      5.             else
      6.             {
      7.                 visibleItems = DataSource.Count;
      8.             }
     
  6. sebastien-barry

    sebastien-barry

    Joined:
    Dec 18, 2013
    Posts:
    53
    Sorry, still having problems with item shifting and a new bug when remove item, you can see both in the following video :
    Sample Video
    and what about clear and Add items in the same function call ?
     
  7. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    Understand, I'll try to find fix for this.

    With last fix it should work fine.
     
    Last edited: Nov 17, 2015
  8. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    TileView.cs, add following line in ScrollUpdate() after "bottomHiddenItems = Mathf.Max(0, DataSource.Count - visibleItems - topHiddenItems);"
    Code (CSharp):
    1.             Debug.Log(String.Format("DestroyGameObjects: {0}; topHiddenItems: {1}; bottomHiddenItems {2}; visibleItems: {3}; components.Count: {4}; DataSource.Count: {5}",
    2.                                    DestroyGameObjects, topHiddenItems, bottomHiddenItems, visibleItems, components.Count, DataSource.Count));
    And tell me what displayed in console when all items visible and when some items missing in last visible row.
     
  9. sebastien-barry

    sebastien-barry

    Joined:
    Dec 18, 2013
    Posts:
    53
    Hi,
    Here a video with the result : Video
     
  10. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    DestroyGameObjects = true. By default it is false - otherwise components cache became pretty meaningless and lead to errors. Suppose somewhere in your code it setted to true.
    Set it to false, this should fix problem.
     
  11. sebastien-barry

    sebastien-barry

    Joined:
    Dec 18, 2013
    Posts:
    53
    I use DestroyGameObject = true with all your components, it works well.
    I prefer using it because I use your Tileview to dynamicly load raw Texture and this take a lot of memory.
    So after the user choose the texture he wants, I can Unload or Destroy (texture source dependant) the unnecessary textures.
    If I don't set DestroyGameObject to true, I can't detroy correctly the texturesy used by the tile view. If I try, it freeze the app and then I get an error message trying to access a texture while destroying...
    So if I don't DestroyGameObject, I use a lot of Ram for nothing.
    It works well with all your components, the trick is to use coroutines.
    Your asset is great, but I think Tileview must support DestroyGameObject as your other components, because it really take less memory.
     
  12. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    Understand, in next update will be added function MovedToCache() in ListViewItem, this function will be called when item moved to cache and you can override it to unload or destroy resources used in ListViewItem.

    Fix for DestroyGameObject = true
    • ListViewBase.cs, add code
      Code (CSharp):
      1.         [NonSerialized]
      2.         protected bool SetItemIndicies = true;
      3.  
    • ListViewBase.cs, replace line in UpdateItems(List<ListViewItem> newItems)
      old line:
      Code (CSharp):
      1.                 x.Index = i;
      new line:
      Code (CSharp):
      1.                 if (SetItemIndicies)
      2.                 {
      3.                     x.Index = i;
      4.                 }
    • ListViewCustom.cs, add line in Start() after "base.Start();"
      Code (CSharp):
      1.             SetItemIndicies = false;
    • ListViewCustom.cs, add this line at end of UpdateComponentsCount()
      Code (CSharp):
      1. base.Items = components.ConvertAll(x => x as ListViewItem);
     
  13. sebastien-barry

    sebastien-barry

    Joined:
    Dec 18, 2013
    Posts:
    53
    Ok,
    the last code fixes items shifting problem,
    Clear function works
    Remove function fails depending the scroll position (even if I don't destroy Textures), here the error :
    MissingReferenceException: The object of type 'TileViewManageComponentTexture' has been destroyed but you are still trying to access it.
    Your script should either check if it is null or you should not destroy the object.
    The error point to TileView.cs - Function ScrollUpdate - line of code : components.OrderBy(x => x.Index).ForEach(x => x.transform.SetAsLastSibling());
     
  14. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    • TileView.cs, add line at start ScrollUpdate()
      Code (CSharp):
      1. RemoveCallbacks();
    • TileView.cs, add line at ScrollUpdate()
      Code (CSharp):
      1. AddCallbacks();
      before line
      Code (CSharp):
      1. components.OrderBy(x => x.Index).ForEach(x => x.transform.SetAsLastSibling());
    • ListViewCustom.cs, add line at start UpdateComponentsCount()
      Code (CSharp):
      1. components.RemoveAll(x => x==null);
     
  15. sebastien-barry

    sebastien-barry

    Joined:
    Dec 18, 2013
    Posts:
    53
    RemoveCallbacks() and AddCallbacks(); functions do not exist in TileView.cs
    DO I change RemoveCallbacks() and AddCallbacks() in ListViewCustom.cs to protected ?
    I changed RemoveCallbacks() and AddCallbacks() to protected functions.
    That's rocks !!!
    It's perfect, no bug anymore !
    Thanks for your support, your reactivity and your help.
     
    Last edited: Nov 17, 2015
  16. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    Yes.
     
  17. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    Version 1.6.5 released.

    Changelog:
    • Added Resizable
    • Added Splitter
    • Added SlideBlock
    • Added ScrollRectEvents component with PullUp, PullDown, PullLeft, PullRight events (use it for refresh or load more options)
    • Removed properties SelectedComponent and SelectedComponents in ListViewCustom
    • ObservableList - you can disable items observe in constructor
    • Added MovedToCache function for ListViewItem, called when item moved to cache, you can use it free used resources
    • Added Table sample (ListViewCustom + ResizableHeader + Tooltip)
    • TileView sample - added Resizable for TileView and TileViewItems and toggle direction
    • Bug fixes
    • Optimization
     
  18. alizdesk

    alizdesk

    Joined:
    Mar 26, 2015
    Posts:
    46
    Awesome Release, with so many great components and updates
    Great Work as usual :D
     
  19. RazaTech

    RazaTech

    Joined:
    Feb 27, 2015
    Posts:
    178
    New components are great , Awesome Job keep it up !!!:)
     
  20. alizdesk

    alizdesk

    Joined:
    Mar 26, 2015
    Posts:
    46
    @ilih
    For some reason, List scrolling performance suffers when items are either too small (10+ item in screen) or too big (1.5-2 items in screen). This sizing/height limitation is not allowing us to create item designs with full freedom. Please advise
     
  21. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    What you see in Profiler window?
    Is problem happens with lists in sample scene if make them small or too big?
    Is asset latest version?
    Unity version?
     
    Last edited: Nov 26, 2015
  22. alizdesk

    alizdesk

    Joined:
    Mar 26, 2015
    Posts:
    46
    I'm using 1.6.5 and Unity 5.2.3p1.
    will send Profile once i get my hands on Device again
     
  23. LuShan

    LuShan

    Joined:
    Jan 28, 2015
    Posts:
    1
    Hi there.
    ListViewBase.cs line 210 might be wrong
    Code (csharp):
    1.  
    2. /// <summary>
    3. /// Determines if item not exists with the specified index.
    4. /// </summary>
    5. /// <returns><c>true</c>, if item not exists, <c>false</c> otherwise.</returns>
    6. /// <param name="index">Index.</param>
    7. protected bool NotIsValid(int index)
    8. {
    9. return IsValid(index);
    10. }
    11.  
    Code (csharp):
    1.  
    2. return IsValid(index);
    3.  
    should be
    Code (csharp):
    1.  
    2. return ! IsValid(index);
    3.  
     
  24. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    Yes, it is mistake, should !IsValid(index).
    Thanks.
     
  25. sebastien-barry

    sebastien-barry

    Joined:
    Dec 18, 2013
    Posts:
    53
    Hi, is it possible to use SortFunc with Treeview ?

    I 've tried and it doesn't really works, there are bugs with child.
    Is there a way to do it ?
     
  26. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    No.

    You can sort TreeView nodes such way:
    Code (CSharp):
    1.         // Compare nodes by Name in ascending order
    2.         Comparison<TreeNode<TreeViewItem>> comparisonAsc = (x, y) => {
    3.             if (x.Item.LocalizedName!=null)
    4.             {
    5.                 return x.Item.LocalizedName.CompareTo(y.Item.LocalizedName ?? y.Item.Name);
    6.             }
    7.             return x.Item.Name.CompareTo(y.Item.LocalizedName ?? y.Item.Name);
    8.         };
    9.  
    10.         // Compare nodes by Name in descending order
    11.         Comparison<TreeNode<TreeViewItem>> comparisonDesc = (x, y) => {
    12.             if (x.Item.LocalizedName!=null)
    13.             {
    14.                 return -x.Item.LocalizedName.CompareTo(y.Item.LocalizedName ?? y.Item.Name);
    15.             }
    16.             return -x.Item.Name.CompareTo(y.Item.LocalizedName ?? y.Item.Name);
    17.         };
    18.  
    19.         public void SortAsc()
    20.         {
    21.             ApplyNodesSort(nodes, comparisonAsc);
    22.         }
    23.  
    24.         public void SortDesc()
    25.         {
    26.             ApplyNodesSort(nodes, comparisonDesc);
    27.         }
    28.  
    29.         void ApplyNodesSort(ObservableList<TreeNode<TreeViewItem>> nodes, Comparison<TreeNode<TreeViewItem>> comparison)
    30.         {
    31.             nodes.Sort(comparison);
    32.             nodes.ForEach(node => {
    33.                 if (node.Nodes!=null)
    34.                 {
    35.                     ApplyNodesSort(node.Nodes as ObservableList<TreeNode<TreeViewItem>>, comparison);
    36.                 }
    37.             });
    38.         }
     
  27. sebastien-barry

    sebastien-barry

    Joined:
    Dec 18, 2013
    Posts:
    53
    It is perfect !

    Thanks
     
  28. sebastien-barry

    sebastien-barry

    Joined:
    Dec 18, 2013
    Posts:
    53
    Hi, I'm creating a treeview where the user can add remove and reorder items.
    I'd like to know how to remove one item from treeview.
    I've tried :
    tree.Remove (removeIndex);
    tree.Nodes.remove
    But I always get the following error : MissingReferenceException: The object of type 'Text' has been destroyed but you are still trying to access it.

    If I uses tree.Remove(TreeNode<ITreeViewSceneObjectItem>)
    How can I get the ListNode<ITreeViewSceneObjectItem> of an item if the item is not selected ?

    This is the code I use for my items delete button, I know it's not the good way to do it and it doesn't work correctly :

    Code (CSharp):
    1. private IObservableList<TreeNode<ITreeViewSceneObjectItem>> GetItemsNodes(TreeViewSceneObjectCustomItem item, IObservableList<TreeNode<ITreeViewSceneObjectItem>> currentNodes)
    2.         {
    3.             for (int i=0; i < currentNodes.Count; i++)
    4.             {
    5.                 TreeViewSceneObjectCustomItem currentItem = ((TreeViewSceneObjectCustomItem)(currentNodes [i].Item));
    6.                 if (currentItem.UniqueIdentifier == item.UniqueIdentifier)
    7.                     return currentNodes;
    8.             }
    9.  
    10.             for (int i=0; i < currentNodes.Count; i++)
    11.             {
    12.                 TreeViewSceneObjectCustomItem currentItem = ((TreeViewSceneObjectCustomItem)(currentNodes [i].Item));
    13.                 IObservableList<TreeNode<ITreeViewSceneObjectItem>> res = GetItemsNodes(item, currentNodes[i].Nodes);
    14.                 if (res != null)
    15.                     return res;
    16.             }
    17.             return null;
    18.              
    19.         }
    20.  
    Code (CSharp):
    1. public void DeleteItem(TreeViewSceneObjectComponent item)
    2.         {
    3.             IObservableList<TreeNode<ITreeViewSceneObjectItem>> nodes = GetItemsNodes(((TreeViewSceneObjectCustomItem)(item.Item)), tree.Nodes);
    4.             int currentPosition = ((TreeViewSceneObjectCustomItem)(item.Item)).Position;
    5.  
    6.             if (nodes != null)
    7.             {
    8.                 nodes.BeginUpdate ();
    9.                 TreeViewSceneObjectCustomItem toRemoveNode = ((TreeViewSceneObjectCustomItem)(item.Item));
    10.  
    11.                 if (toMoveNode.IsLast)
    12.                 {
    13.                     if (nodes.Count > 1)
    14.                         ((TreeViewSceneObjectCustomItem)(nodes [currentPosition - 1].Item)).IsLast = true;
    15.  
    16.                 }
    17.                 else
    18.                 {
    19.                     for (int i = currentPosition + 1; i < nodes.Count; i++)
    20.                     {
    21.                         ((TreeViewSceneObjectCustomItem)(nodes [i].Item)).Position -= 1;
    22.                     }
    23.                 }
    24.                 //nodes.RemoveAt (currentPosition);
    25.                 nodes.EndUpdate ();
    26.                 nodes.RemoveAt (currentPosition);
    27.  
    28.             }
    29.             else
    30.             {
    31.                 Debug.Log ("Node not found");
    32.             }
    33.         }
    34.  
     
  29. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    Here is code to delete item from TreeView.
    Code (CSharp):
    1.         public bool Remove<T>(ObservableList<TreeNode<T>> nodes, Predicate<TreeNode<T>> match)
    2.         {
    3.             var index = nodes.FindIndex(match);
    4.             if (index!=-1)
    5.             {
    6.                 nodes.RemoveAt(index);
    7.                 return true;
    8.             }
    9.             foreach (var node in nodes)
    10.             {
    11.                 if (node.Nodes==null)
    12.                 {
    13.                     continue ;
    14.                 }
    15.                 if (Remove(node.Nodes as ObservableList<TreeNode<T>>, match))
    16.                 {
    17.                     return true;
    18.                 }
    19.             }
    20.             return false;
    21.         }
    And how to use it:
    Code (CSharp):
    1.         public void RemoveByName(ObservableList<TreeNode<TreeViewItem>> nodes, string name)
    2.         {
    3.             var removed = Remove(nodes, x => x.Item.Name==name);
    4.             Debug.Log(name + ": " + removed);
    5.         }
    6.  
    7.         public void RemoveByID(ObservableList<TreeNode<ITreeViewSceneObjectItem>> nodes, TreeViewSceneObjectCustomItem item)
    8.         {
    9.             var removed = Remove(nodes, x => x.Item.UniqueIdentifier==item.UniqueIdentifier);
    10.             Debug.Log(item.UniqueIdentifier + ": " + removed);
    11.         }
    12.  
    13.         public void TestRemove(string name)
    14.         {
    15.             RemoveByName(nodes, name);
    16.         }
    And code for reorder:
    Code (CSharp):
    1.         public bool ChangePosition<T>(ObservableList<TreeNode<T>> nodes, Predicate<TreeNode<T>> match, int position)
    2.         {
    3.             var findedNode = nodes.Find(match);
    4.             if (findedNode!=null)
    5.             {
    6.                 nodes.Remove(findedNode);
    7.                 nodes.Insert(position, findedNode);
    8.                 return true;
    9.             }
    10.             foreach (var node in nodes)
    11.             {
    12.                 if (node.Nodes==null)
    13.                 {
    14.                     continue ;
    15.                 }
    16.                 if (ChangePosition(node.Nodes as ObservableList<TreeNode<T>>, match, position))
    17.                 {
    18.                     return true;
    19.                 }
    20.             }
    21.             return false;
    22.         }
    23.      
    24.         public void ChangePositionByName(ObservableList<TreeNode<TreeViewItem>> nodes, string name, int position)
    25.         {
    26.             var changed = ChangePosition(nodes, x => x.Item.Name==name, position);
    27.             Debug.Log(name + ": " + changed);
    28.         }
    29.  
    30.         public void TestReorder(string name)
    31.         {
    32.             ChangePositionByName(nodes, name, 3);
    33.         }
     
  30. sebastien-barry

    sebastien-barry

    Joined:
    Dec 18, 2013
    Posts:
    53
    Hi,the remove function works great,
    A little problem with ChangePosition, I use tree.DestroyGameObjects = true and I can't do :
    nodes.Remove(findedNode); and immediatly
    nodes.Insert(position, findedNode);
    The treeview do not correctly refresh, the only way is to use a couroutine and WaitForEndOfFrame to do the insert.
     
  31. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    Please try:
    Code (CSharp):
    1.                 nodes.BeginUpdate();
    2.                 nodes.Remove(findedNode);
    3.                 nodes.Insert(position, findedNode);
    4.                 nodes.EndUpdate();
    I think this probably help, but I cannot reproduce this bug, so not sure.
     
  32. sebastien-barry

    sebastien-barry

    Joined:
    Dec 18, 2013
    Posts:
    53
    Perfect, once again thanks.
     
  33. alizdesk

    alizdesk

    Joined:
    Mar 26, 2015
    Posts:
    46
  34. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    Here is sample, how it can be done for ListViewIcons
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using UIWidgets;
    4.  
    5. namespace UIWidgetsSamples {
    6.     [RequireComponent(typeof(ScrollRectEvents))]
    7.     public class TestScrollRectEvents : MonoBehaviour {
    8.         [SerializeField]
    9.         public ListViewIcons ListView;
    10.  
    11.         void Start()
    12.         {
    13.             ListView.Sort = false;
    14.  
    15.             // subscribe on events
    16.             var scrollRectEvents = GetComponent<ScrollRectEvents>();
    17.             if (scrollRectEvents!=null)
    18.             {
    19.                 scrollRectEvents.OnPullUp.AddListener(Refresh);
    20.                 scrollRectEvents.OnPullDown.AddListener(LoadMore);
    21.             }
    22.         }
    23.  
    24.         public void Refresh()
    25.         {
    26.             // add some items at start
    27.             ListView.DataSource.Insert(0, new ListViewIconsItemDescription(){Name = "added at start"});
    28.             // or load from some site
    29.             //StartCoroutine(RefreshData());
    30.         }
    31.  
    32.         IEnumerator RefreshData()
    33.         {
    34.             WWW www = new WWW("some url");
    35.             yield return www;
    36.          
    37.             var dataSource = ListView.DataSource;
    38.             dataSource.BeginUpdate();
    39.             dataSource.Clear();
    40.             www.text.Split('\n').ForEach(x => {
    41.                 dataSource.Add(new ListViewIconsItemDescription(){Name = x});
    42.             });
    43.             dataSource.EndUpdate();
    44.         }
    45.  
    46.         public void LoadMore()
    47.         {
    48.             // add some items at end
    49.             ListView.DataSource.Add(new ListViewIconsItemDescription(){Name = "added at end"});
    50.             //or load from some site
    51.             //StartCoroutine(LoadMoreData());
    52.         }
    53.  
    54.         IEnumerator LoadMoreData()
    55.         {
    56.             WWW www = new WWW("some url");
    57.             yield return www;
    58.  
    59.             var dataSource = ListView.DataSource;
    60.             dataSource.BeginUpdate();
    61.             www.text.Split('\n').ForEach(x => {
    62.                 dataSource.Add(new ListViewIconsItemDescription(){Name = x});
    63.             });
    64.             dataSource.EndUpdate();
    65.         }
    66.  
    67.         void OnDestroy()
    68.         {
    69.             // unsubscribe
    70.             var scrollRectEvents = GetComponent<ScrollRectEvents>();
    71.             if (scrollRectEvents!=null)
    72.             {
    73.                 scrollRectEvents.OnPullUp.RemoveListener(Refresh);
    74.                 scrollRectEvents.OnPullDown.RemoveListener(LoadMore);
    75.             }
    76.         }
    77.     }
    78. }
     
  35. alizdesk

    alizdesk

    Joined:
    Mar 26, 2015
    Posts:
    46
    Thanks, it'd be great if you also provide a working example in your next update.
     
  36. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    Probably.
     
  37. sebastien-barry

    sebastien-barry

    Joined:
    Dec 18, 2013
    Posts:
    53
    Hi,
    There is a bug in the editor with Spinner, don't know if it comes from 1.6.5 or Unity 5.3.0 f2
    It works well in GameView and build.
    Here the bug :
    Add a Spinner
    Click on SpinnerInput child
    The following message appear in the Console :

    NullReferenceException: Object reference not set to an instance of an object
    UIWidgets.Utilites.CreateObject (System.String path, UnityEngine.Transform parent) (at Assets/FxController/FxAssets/UIWidgets/Standart Assets/Utilites/Utilites.cs:36)
    UIWidgets.Utilites.CreateObjectFromAsset (System.String searchString, System.String undoName) (at Assets/FxController/FxAssets/UIWidgets/Standart Assets/Utilites/Utilites.cs:69)
    UIWidgets.Utilites.CreateWidgetFromAsset (System.String widget) (at Assets/FxController/FxAssets/UIWidgets/Standart Assets/Utilites/Utilites.cs:77)
    UIWidgets.Spinner.CreateObject () (at Assets/FxController/FxAssets/UIWidgets/Standart Assets/Spinner/Spinner.cs:189)

    There are also warnings with /SpinnerBase.cs(214,30): warning CS0618: `UnityEngine.UI.InputField.onValueChange' is obsolete: `onValueChange has been renamed to onValueChanged'
     
  38. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    Bug happens when Canvas not present on scene.
    Fix (it's create canvas if it not exists):
    1. Utilites.cs, add
      Code (CSharp):
      1. using UnityEngine.EventSystems;
    2. Add following after CreateObject() method
      Code (CSharp):
      1.         /// <summary>
      2.         /// Gets the canvas transform.
      3.         /// </summary>
      4.         /// <returns>The canvas transform.</returns>
      5.         static public Transform GetCanvasTransform()
      6.         {
      7.             var canvas = (Selection.activeGameObject!=null) ? Selection.activeGameObject.GetComponentInParent<Canvas>() : null;
      8.             if (canvas==null)
      9.             {
      10.                 canvas = UnityEngine.Object.FindObjectOfType<Canvas>();
      11.             }
      12.             if (canvas!=null)
      13.                 return canvas.transform;
      14.            
      15.             var canvasGO = new GameObject("Canvas");
      16.             canvasGO.layer = LayerMask.NameToLayer("UI");
      17.             canvas = canvasGO.AddComponent<Canvas>();
      18.             canvas.renderMode = RenderMode.ScreenSpaceOverlay;
      19.             canvasGO.AddComponent<CanvasScaler>();
      20.             canvasGO.AddComponent<GraphicRaycaster>();
      21.             Undo.RegisterCreatedObjectUndo(canvasGO, "Create " + canvasGO.name);
      22.            
      23.             if (UnityEngine.Object.FindObjectOfType<EventSystem>()==null)
      24.             {
      25.                 var eventSystemGO = new GameObject("EventSystem");
      26.                 eventSystemGO.AddComponent<EventSystem>();
      27.                 eventSystemGO.AddComponent<StandaloneInputModule>();
      28.                 eventSystemGO.AddComponent<TouchInputModule>();
      29.                
      30.                 Undo.RegisterCreatedObjectUndo(eventSystemGO, "Create " + eventSystemGO.name);
      31.             }
      32.  
      33.             return canvasGO.transform;
      34.         }
    3. Replace line (it should be line 37 after previous changes)
      Code (CSharp):
      1. go_parent = UnityEngine.Object.FindObjectOfType<Canvas>().transform;
      with new line
      Code (CSharp):
      1. go_parent = GetCanvasTransform();

    Probably changing line 214 in SpinnerBase.cs should be enough (Unity 5.3 not officially released, so I cannot check it).
    Code (CSharp):
    1. base.onValueChanged.AddListener(ValueChange);
     
  39. Nick_Koufou

    Nick_Koufou

    Joined:
    Apr 26, 2008
    Posts:
    9
    Hi, it appears there is an issue with blowing up the stack when a TileView/ListView has 0 items. Basically a call to ScrollUpdate is made when the last item from the TileView is removed. This will call SetScrollValue which will in turn call ScrollUpdate again and so on and so on because of the following condition being true:

    if (new_position != current_position)

    current_position.x = 0
    current_position.y = 1.525879E-05

    new_position.x=0
    new_position.y=0

    Now in theory when the anchoredPosition is set then on the next iteration the conditional should return false and all should be fine: scrollRect.content.anchoredPosition = new_position;

    For some reason though that is not the case as the assignment is ignored, maybe Unity is doing some internal comparison and does not set anchoredPosition when the difference is very small. As a temporary hack I added the following line just before the assignment to new_position: scrollRect.content.anchoredPosition = Vector2.one; maybe you can figure out a better way of dealing with this.

    Callstack:

    UIWidgets.ListViewCustom<object,object>.SetScrollValue (value=0) in ListViewCustom.cs:711
    UIWidgets.TileView<object,object>.ScrollUpdate () in TileView.cs:113
    UIWidgets.ListViewCustom<object,object>.SetScrollValue (value=0) in ListViewCustom.cs:712
    UIWidgets.ListViewCustom<object,object>.UpdateView () in ListViewCustom.cs:1163
    UIWidgets.ListViewCustom<object,object>.SetNewItems (newItems={UIWidgets.ObservableList<TileViewSoldierInfo>}) in ListViewCustom.cs:1211
    UIWidgets.ListViewCustom<object,object>.UpdateItems () in ListViewCustom.cs:642
    UIWidgets.ObservableList<object>.Changed () in ObservableList.cs:127
    UIWidgets.ObservableList<object>.RemoveAt (index=0) in ObservableList.cs:309
    UIWidgets.ListViewCustom<object,object>.Remove (index=0) in ListViewCustom.cs:696
     
  40. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    This should fix problem:
    1. Replace SetScrollValue() in ListViewCustom.cs
      Code (CSharp):
      1.         protected void SetScrollValue(float value, bool callScrollUpdate=true)
      2.         {
      3.             var current_position = scrollRect.content.anchoredPosition;
      4.             var new_position = IsHorizontal()
      5.                 ? new Vector2(value, current_position.y)
      6.                 : new Vector2(current_position.x, value);
      7.  
      8.             var diff_x = IsHorizontal() ? Mathf.Abs(current_position.x - new_position.x) > 0.1f : false;
      9.             var diff_y = IsHorizontal() ? false : Mathf.Abs(current_position.y - new_position.y) > 0.1f;
      10.             if (diff_x || diff_y)
      11.             {
      12.                 scrollRect.content.anchoredPosition = new_position;
      13.                 if (callScrollUpdate)
      14.                 {
      15.                     ScrollUpdate();
      16.                 }
      17.             }
      18.         }
    2. Replace line 113 in TileView.cs
      old line:
      Code (CSharp):
      1. SetScrollValue(0f);
      new line:
      Code (CSharp):
      1. SetScrollValue(0f, false);
     
    Nick_Koufou likes this.
  41. sebastien-barry

    sebastien-barry

    Joined:
    Dec 18, 2013
    Posts:
    53
    "Bug happens when Canvas not present on scene" : The problem is that I already have a canvas, there is the same problem in your demo scene, I cannot change my Spinner max, min ... values cause the problem occurs when you click on the subObject SpinnerInput in the editors.
     
  42. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    I check it in Unity 5.3, it's related with 5.3 changes.
    Fix:
    Editor/SpinnerEditor.cs
    • lines 23 and 100: change "m_OnValueChange" on "m_OnValueChanged".
    • lines 24 and 101: change "m_EndEdit" on "m_OnEndEdit".
    Editor/SpinnerFloatEditor.cs
    • lines 23 and 102: change "m_OnValueChange" on "m_OnValueChanged".
    • lines 24 and 103: change "m_EndEdit" on "m_OnEndEdit".
     
  43. sebastien-barry

    sebastien-barry

    Joined:
    Dec 18, 2013
    Posts:
    53
    Perfect !

    Thanks
     
  44. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    Version 1.7.0 released.

    Changelog:
    • Added Drag and Drop support
    • ComboboxCustom and ComboboxIcons: Added Multiselect support
    • ResizableHeader: Added drag column support
    • TreeViewItem: Added Tag property
    • SlideBlock: Optional support for children ScrollRect
    • Accordion: Added Direction
    • Accordion: Added support Horizontal Layout Group and Vertical Layout Group (Content Objects should have LayoutElement component)
    • ListViews: Added limited support Horizontal Layout Group and Vertical Layout Group (you cannot change ListView direction in runtime)
    • ObservableList: Added events OnCollectionChange (raised when items added, removed or replaced) and OnCollectionItemChange (raised when item in collection raise OnChange or PropertyChanged events)
    • ObservableList: Added Comparison, ResortOnCollectionChanged, ResortOnCollectionItemChanged properties
    • TreeNode: Added Parent property. Now you can remove node from tree using Node.Parent = null or move node to another subtree Node.Parent = AnotherNode
    • Bug fixes
     
    Last edited: Dec 15, 2015
    Tinjaw likes this.
  45. snake1029

    snake1029

    Joined:
    Dec 16, 2015
    Posts:
    6
    HI ilih, thanks for the great asset.
    and i want to ask how can i delete a defaultItem with button.
    if i do destroy(gameobject) then i got error.
    the screen like this.


    thanks
     

    Attached Files:

  46. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    • Add similar code to your ListViewComponent script and
      Code (CSharp):
      1.         public YourListView List;
      2.  
      3.         public void Remove()
      4.         {
      5.             List.DataSource.RemoveAt(Index);
      6.         }
    • Specify List in Inspector window
    • Add Remove() call on Button.OnClick()
     
  47. snake1029

    snake1029

    Joined:
    Dec 16, 2015
    Posts:
    6
    Thank ilih very much for the quick response and it work's perfect ! !
     
  48. snake1029

    snake1029

    Joined:
    Dec 16, 2015
    Posts:
    6
    hi ilih again , may i ask how to save my listview index when i close the application ? and restore when i open it
     
  49. ilih

    ilih

    Joined:
    Aug 6, 2013
    Posts:
    839
    Easiest way is save index with PlayerPrefs.
    You can use this script with any ListView or TileView.
    Code (CSharp):
    1. using UnityEngine;
    2. using UIWidgets;
    3. using System.Linq;
    4.  
    5. namespace UIWidgetsSamples {
    6.     [RequireComponent(typeof(ListViewBase))]
    7.     public class ListViewSaveIndicies : MonoBehaviour {
    8.         [SerializeField]
    9.         string Key = "Unique Key";
    10.  
    11.         ListViewBase list;
    12.  
    13.         void Start()
    14.         {
    15.             list = GetComponent<ListViewBase>();
    16.             list.Start();
    17.             LoadIndicies();
    18.  
    19.             list.OnSelect.AddListener(SaveIndicies);
    20.             list.OnDeselect.AddListener(SaveIndicies);
    21.         }
    22.  
    23.         void LoadIndicies()
    24.         {
    25.             if (PlayerPrefs.HasKey(Key))
    26.             {
    27.                 var indicies = PlayerPrefs.GetString(Key).Split(',').Select(x => int.Parse(x)).ToList();
    28.                 list.SelectedIndicies = indicies;
    29.             }
    30.         }
    31.  
    32.         void SaveIndicies(int index, ListViewItem component)
    33.         {
    34.             var str = string.Join(",", list.SelectedIndicies.Select(x => x.ToString()).ToArray());
    35.             PlayerPrefs.SetString(Key, str);
    36.         }
    37.     }
    38. }
     
  50. snake1029

    snake1029

    Joined:
    Dec 16, 2015
    Posts:
    6
    thank ilih again ! i'll try it later
     
unityunity