[NUI] Add GridRecycleLayotManager (#1685)
authorneostom432 <31119276+neostom432@users.noreply.github.com>
Thu, 11 Jun 2020 05:28:06 +0000 (14:28 +0900)
committerGitHub <noreply@github.com>
Thu, 11 Jun 2020 05:28:06 +0000 (14:28 +0900)
Grid Layout for RecyclerView.

When user set Orientation, GridRecycleLayoutManager will lay out items using only one factor between Row and Column.

Horizontal => Row
Vertical => Column

src/Tizen.NUI.Components/Controls/RecyclerView/GridRecycleLayoutManager.cs [new file with mode: 0644]
src/Tizen.NUI.Components/Controls/RecyclerView/LinearRecycleLayoutManager.cs [moved from src/Tizen.NUI.Components/Controls/RecyclerView/LinearLayoutManager.cs with 93% similarity]
src/Tizen.NUI.Components/Controls/RecyclerView/RecycleLayoutManager.cs [moved from src/Tizen.NUI.Components/Controls/RecyclerView/LayoutManager.cs with 82% similarity]
src/Tizen.NUI.Components/Controls/RecyclerView/RecyclerView.cs
src/Tizen.NUI.Components/Controls/ScrollableBase.cs
src/Tizen.NUI.Wearable/src/internal/FishEyeLayoutManager.cs
src/Tizen.NUI.Wearable/src/public/WearableList.cs

diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/GridRecycleLayoutManager.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/GridRecycleLayoutManager.cs
new file mode 100644 (file)
index 0000000..bf995b0
--- /dev/null
@@ -0,0 +1,254 @@
+/* Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+using System;
+using Tizen.NUI.BaseComponents;
+using System.Collections.Generic;
+using System.ComponentModel;
+
+namespace Tizen.NUI.Components
+{
+    /// <summary>
+    /// [Draft] This class implements a grid box layout.
+    /// </summary>
+    /// <since_tizen> 8 </since_tizen>
+    /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class GridRecycleLayoutManager : RecycleLayoutManager
+    {
+        private int rows = 1;
+
+        /// <summary>
+        /// [draft ]Get/Set the number of rows in the grid
+        /// </summary>
+        /// <since_tizen> 8 </since_tizen>
+        // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public int Rows
+        {
+            get
+            {
+                return rows;
+            }
+            set
+            {
+                rows = value;
+
+                if (Container != null)
+                {
+                    Layout(mPrevScrollPosition);
+                }
+            }
+        }
+
+        private int columns = 1;
+
+
+        /// <summary>
+        /// [Draft] Get/Set the number of columns in the grid
+        /// </summary>
+        /// <since_tizen> 8 </since_tizen>
+        // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public int Columns
+        {
+            get
+            {
+                return columns;
+            }
+            set
+            {
+                columns = value;
+
+                if (Container != null)
+                {
+                    Layout(mPrevScrollPosition);
+                }
+            }
+        }
+
+        private int firstVisibleItemIndex = -1;
+        private int lastVisibleItemIndex = -1;
+
+        private bool IsItemVisible(float scrollPosition, RecycleItem item)
+        {
+            bool result = false;
+            View list = Container.GetParent() as View;
+
+            Vector2 visibleArea = new Vector2(Math.Abs(scrollPosition),
+                Math.Abs(scrollPosition) + (LayoutOrientation == Orientation.Horizontal ?
+                                                list.Size.Width : list.Size.Height)
+            );
+
+            float firstCheckPoint = LayoutOrientation == Orientation.Horizontal ? item.Position.X : item.Position.Y;
+            float secondCheckPoint = LayoutOrientation == Orientation.Horizontal ?
+                                        firstCheckPoint + item.Size.Width :
+                                        firstCheckPoint + item.Size.Height;
+
+            result = (firstCheckPoint >= visibleArea.X && firstCheckPoint <= visibleArea.Y) || (secondCheckPoint >= visibleArea.X && secondCheckPoint <= visibleArea.Y);
+
+            return result;
+        }
+
+        /// <summary>
+        /// This is called to find out how much container size can be.
+        /// </summary>
+        /// <since_tizen> 8 </since_tizen>
+        /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override float CalculateLayoutOrientationSize()
+        {
+            float orientationFactor = LayoutOrientation == Orientation.Horizontal ? Rows : Columns;
+            return mStepSize * (int)Math.Ceiling((double)DataCount / (double)orientationFactor);
+        }
+
+
+        /// <summary>
+        /// This is called to find out where items are lain out according to current scroll position.
+        /// </summary>
+        /// <param name="scrollPosition">Scroll position which is calculated by ScrollableBase</param>
+        /// <since_tizen> 8 </since_tizen>
+        /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
+        public override void Layout(float scrollPosition)
+        {
+            int itemInGroup = LayoutOrientation == Orientation.Horizontal ? Rows : Columns;
+            firstVisibleItemIndex = -1;
+            lastVisibleItemIndex = -1;
+
+            RecycleItem previousItem = null;
+
+            for (int i = 0; i < Container.Children.Count; i++)
+            {
+                RecycleItem item = Container.Children[i] as RecycleItem;
+
+                if (previousItem != null)
+                {
+                    item.Position = LayoutOrientation == Orientation.Horizontal ?
+                        new Position(
+                            (i % itemInGroup == 0 ?
+                            previousItem.Position.X + (previousItem.CurrentSize.Width != 0 ?
+                                                            previousItem.CurrentSize.Width :
+                                                            previousItem.Size.Width) :
+                            previousItem.Position.X),
+                            (i % itemInGroup == 0 ?
+                            0 :
+                            previousItem.PositionY + (previousItem.CurrentSize.Height != 0 ?
+                                                            previousItem.CurrentSize.Height :
+                                                            previousItem.Size.Height))
+                        ) :
+                        new Position(
+                            (i % itemInGroup == 0 ?
+                            0 :
+                            previousItem.PositionX + (previousItem.CurrentSize.Width != 0 ?
+                                                            previousItem.CurrentSize.Width :
+                                                            previousItem.Size.Width)),
+                            (i % itemInGroup == 0 ?
+                            previousItem.Position.Y + (previousItem.CurrentSize.Height != 0 ?
+                                                            previousItem.CurrentSize.Height :
+                                                            previousItem.Size.Height) :
+                            previousItem.Position.Y)
+                        );
+                }
+
+                bool isVisible = IsItemVisible(scrollPosition, item);
+
+                if (isVisible)
+                {
+                    firstVisibleItemIndex = firstVisibleItemIndex == -1 ? i : firstVisibleItemIndex;
+                    lastVisibleItemIndex = i;
+                }
+
+                previousItem = item;
+            }
+
+            if (mStepSize == 0)
+            {
+                mStepSize = LayoutOrientation == Orientation.Horizontal ? ItemSize.Width : ItemSize.Height;
+            }
+        }
+
+
+        /// <summary>
+        /// This is called to find out which items should be recycled according to current scroll position.
+        /// </summary>
+        /// <param name="scrollPosition">Scroll position which is calculated by ScrollableBase</param>
+        /// <returns>List of RecycleItems which should be recycled.</returns>
+        /// <since_tizen> 8 </since_tizen>
+        /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
+        public override List<RecycleItem> Recycle(float scrollPosition)
+        {
+            List<RecycleItem> result = new List<RecycleItem>();
+            bool checkFront = (mPrevScrollPosition - scrollPosition) > 0;
+
+            int itemInGroup = LayoutOrientation == Orientation.Horizontal ? Rows : Columns;
+
+            if (checkFront)
+            {
+                int currentGroupNum = (int)(firstVisibleItemIndex / itemInGroup) + 1;
+
+                if (currentGroupNum > 2)
+                {
+                    // Too many item is in front!!! move first item to back!!!!
+                    for (int i = 0; i < itemInGroup; i++)
+                    {
+                        RecycleItem target = Container.Children[0] as RecycleItem;
+                        target.DataIndex = target.DataIndex + Container.Children.Count;
+                        target.SiblingOrder = Container.Children.Count - 1;
+
+                        result.Add(target);
+                    }
+                }
+            }
+            else
+            {
+                int currentGroupNum = (int)(lastVisibleItemIndex / itemInGroup) + 1;
+
+                if (currentGroupNum < (int)(Container.Children.Count / itemInGroup) - 3)
+                {
+                    for (int i = 0; i < itemInGroup; i++)
+                    {
+                        RecycleItem prevFirstItem = Container.Children[itemInGroup] as RecycleItem;
+
+                        RecycleItem target = Container.Children[Container.Children.Count - 1] as RecycleItem;
+                        target.Position = new Position(
+                            LayoutOrientation == Orientation.Horizontal ? (prevFirstItem.Position.X - target.Size.Width) : prevFirstItem.Position.X,
+                            LayoutOrientation == Orientation.Horizontal ? prevFirstItem.Position.Y : (prevFirstItem.Position.Y - target.Size.Height)
+                        );
+                        target.DataIndex = target.DataIndex - Container.Children.Count;
+                        target.SiblingOrder = 0;
+
+                        result.Add(target);
+                    }
+                }
+            }
+
+
+            mPrevScrollPosition = scrollPosition;
+
+            return result;
+        }
+
+        /// <summary>
+        /// Adjust scrolling position by own scrolling rules.
+        /// </summary>
+        /// <param name="scrollPosition">Scroll position which is calculated by ScrollableBase</param>
+        /// <since_tizen> 8 </since_tizen>
+        /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
+        public override float CalculateCandidateScrollPosition(float scrollPosition)
+        {
+            return scrollPosition;
+        }
+    }
+}
\ No newline at end of file
@@ -26,7 +26,7 @@ namespace Tizen.NUI.Components
     /// <since_tizen> 8 </since_tizen>
     /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
     [EditorBrowsable(EditorBrowsableState.Never)]
-    public class LinearListLayoutManager : LayoutManager
+    public class LinearRecycleLayoutManager : RecycleLayoutManager
     {
         private int firstVisibleItemIndex = -1;
         private int lastVisibleItemIndex = -1;
@@ -108,6 +108,17 @@ namespace Tizen.NUI.Components
         }
 
         /// <summary>
+        /// This is called to find out how much container size can be.
+        /// </summary>
+        /// <since_tizen> 8 </since_tizen>
+        /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public override float CalculateLayoutOrientationSize()
+        {
+            return mStepSize * DataCount;
+        }
+
+        /// <summary>
         /// This is called to find out which items should be recycled according to current scroll position.
         /// </summary>
         /// <param name="scrollPosition">Scroll position which is calculated by ScrollableBase</param>
@@ -26,7 +26,7 @@ namespace Tizen.NUI.Components
     /// <since_tizen> 8 </since_tizen>
     /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
     [EditorBrowsable(EditorBrowsableState.Never)]
-    public class LayoutManager
+    public class RecycleLayoutManager
     {
         protected float mPrevScrollPosition = 0.0f;
         protected int mPrevFirstDataIndex = 0;
@@ -69,6 +69,7 @@ namespace Tizen.NUI.Components
         /// </summary>
         /// <since_tizen> 8 </since_tizen>
         /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public Size ItemSize{get;set;} = new Size();
  
         /// <summary>
@@ -76,6 +77,7 @@ namespace Tizen.NUI.Components
         /// </summary>
         /// <since_tizen> 8 </since_tizen>
         /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public Orientation LayoutOrientation{get;set;} = Orientation.Vertical;
 
         /// <summary>
@@ -83,6 +85,7 @@ namespace Tizen.NUI.Components
         /// </summary>
         /// <since_tizen> 8 </since_tizen>
         /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public float StepSize{
             get
             {
@@ -91,23 +94,44 @@ namespace Tizen.NUI.Components
         }
 
         /// <summary>
+        /// How far can you reach the next item.
+        /// </summary>
+        /// <since_tizen> 8 </since_tizen>
+        /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public int DataCount{get; set;}
+
+        /// <summary>
         /// This is called to find out where items are lain out according to current scroll position.
         /// </summary>
         /// <param name="scrollPosition">Scroll position which is calculated by ScrollableBase</param>
         /// <since_tizen> 8 </since_tizen>
         /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public virtual void Layout(float scrollPosition)
         {
            
         }
 
         /// <summary>
+        /// This is called to find out how much container size can be.
+        /// </summary>
+        /// <since_tizen> 8 </since_tizen>
+        /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public virtual float CalculateLayoutOrientationSize()
+        {
+            return 0.0f;
+        }
+
+        /// <summary>
         /// This is called to find out which items should be recycled according to current scroll position.
         /// </summary>
         /// <param name="scrollPosition">Scroll position which is calculated by ScrollableBase</param>
         /// <returns>List of RecycleItems which should be recycled.</returns>
         /// <since_tizen> 8 </since_tizen>
         /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public virtual List<RecycleItem> Recycle(float scrollPosition)
         {
             return new List<RecycleItem>();
@@ -119,6 +143,7 @@ namespace Tizen.NUI.Components
         /// <param name="scrollPosition">Scroll position which is calculated by ScrollableBase</param>
         /// <since_tizen> 8 </since_tizen>
         /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
+        [EditorBrowsable(EditorBrowsableState.Never)]
         public virtual float CalculateCandidateScrollPosition(float scrollPosition)
         {
             return scrollPosition;
index f6d20e3..5faf016 100644 (file)
@@ -29,10 +29,15 @@ namespace Tizen.NUI.Components
     {
         protected RecycleAdapter mAdapter;
         protected View mContainer;
-        protected LayoutManager mLayoutManager;
+        protected RecycleLayoutManager mLayoutManager;
         protected int mTotalItemCount = 15;
         private List<PropertyNotification> notifications = new List<PropertyNotification>();
 
+        public RecyclerView()
+        {
+            Initialize(new RecycleAdapter(), new RecycleLayoutManager());
+        }
+
         /// <summary>
         /// Default constructor.
         /// </summary>
@@ -41,7 +46,12 @@ namespace Tizen.NUI.Components
         /// <since_tizen> 8 </since_tizen>
         /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public RecyclerView(RecycleAdapter adapter, LayoutManager layoutManager)
+        public RecyclerView(RecycleAdapter adapter, RecycleLayoutManager layoutManager)
+        {
+            Initialize(adapter, layoutManager);
+        }
+
+        private void Initialize(RecycleAdapter adapter, RecycleLayoutManager layoutManager)
         {
             Name = "[List]";
             mContainer = new View()
@@ -64,6 +74,37 @@ namespace Tizen.NUI.Components
             mLayoutManager = layoutManager;
             mLayoutManager.Container = mContainer;
             mLayoutManager.ItemSize = mAdapter.CreateRecycleItem().Size;
+            mLayoutManager.DataCount = mAdapter.Data.Count;
+
+            InitializeItems();
+        }
+
+        private void OnItemSizeChanged(object source, PropertyNotification.NotifyEventArgs args)
+        {
+            mLayoutManager.Layout(ScrollingDirection == Direction.Horizontal ? mContainer.CurrentPosition.X : mContainer.CurrentPosition.Y);
+        }
+        
+        public int TotalItemCount 
+        {
+            get
+            {
+                return mTotalItemCount;
+            }
+            set
+            {
+                mTotalItemCount = value;
+                InitializeItems();
+            }
+        }
+
+        private void InitializeItems()
+        {
+            for(int i = mContainer.Children.Count -1 ; i > -1 ; i--)
+            {
+                mContainer.Children[i].Unparent();
+                notifications[i].Notified -= OnItemSizeChanged;
+                notifications.RemoveAt(i);
+            }
 
             for (int i = 0; i < mTotalItemCount; i++)
             {
@@ -78,10 +119,7 @@ namespace Tizen.NUI.Components
                 mContainer.Add(item);
 
                 PropertyNotification noti = item.AddPropertyNotification("size", PropertyCondition.Step(0.1f));
-                noti.Notified += (object source, PropertyNotification.NotifyEventArgs args) =>
-                {
-                    mLayoutManager.Layout(ScrollingDirection == Direction.Horizontal ? mContainer.CurrentPosition.X : mContainer.CurrentPosition.Y);
-                };
+                noti.Notified += OnItemSizeChanged;
                 notifications.Add(noti);
             }
 
@@ -89,11 +127,33 @@ namespace Tizen.NUI.Components
 
             if (ScrollingDirection == Direction.Horizontal)
             {
-                mContainer.SizeWidth = mLayoutManager.StepSize * mAdapter.Data.Count;
+                mContainer.SizeWidth = mLayoutManager.CalculateLayoutOrientationSize();
             }
             else
             {
-                mContainer.SizeHeight = mLayoutManager.StepSize * mAdapter.Data.Count;
+                mContainer.SizeHeight = mLayoutManager.CalculateLayoutOrientationSize();
+            }
+        }
+
+
+        public new Direction ScrollingDirection
+        {
+            get
+            {
+                return base.ScrollingDirection;
+            }
+            set
+            {
+                base.ScrollingDirection = value;
+
+                if (ScrollingDirection == Direction.Horizontal)
+                {
+                    mContainer.SizeWidth = mLayoutManager.CalculateLayoutOrientationSize();
+                }
+                else
+                {
+                    mContainer.SizeHeight = mLayoutManager.CalculateLayoutOrientationSize();
+                }
             }
         }
 
@@ -109,6 +169,19 @@ namespace Tizen.NUI.Components
             {
                 return mAdapter;
             }
+            set
+            {
+                if(mAdapter != null)
+                {
+                    mAdapter.OnDataChanged -= OnAdapterDataChanged;
+                }
+
+                mAdapter = value;
+                mAdapter.OnDataChanged += OnAdapterDataChanged;
+                mLayoutManager.ItemSize = mAdapter.CreateRecycleItem().Size;
+                mLayoutManager.DataCount = mAdapter.Data.Count;
+                InitializeItems();
+            }
         }
 
         /// <summary>
@@ -117,12 +190,20 @@ namespace Tizen.NUI.Components
         /// <since_tizen> 8 </since_tizen>
         /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public LayoutManager ListLayoutManager
+        public RecycleLayoutManager LayoutManager
         {
             get
             {
                 return mLayoutManager;
             }
+            set
+            {
+                mLayoutManager = value;
+                mLayoutManager.Container = mContainer;
+                mLayoutManager.ItemSize = mAdapter.CreateRecycleItem().Size;
+                mLayoutManager.DataCount = mAdapter.Data.Count;
+                InitializeItems();
+            }
         }
 
         private void OnScroll(object source, ScrollableBase.ScrollEventArgs args)
@@ -151,6 +232,7 @@ namespace Tizen.NUI.Components
                 if (item.DataIndex > -1 && item.DataIndex < mAdapter.Data.Count)
                 {
                     item.Show();
+                    item.Name = "["+item.DataIndex+"]";
                     mAdapter.BindData(item);
                 }
                 else
index 1f7d0a0..2583528 100755 (executable)
@@ -425,6 +425,7 @@ namespace Tizen.NUI.Components
                 }
 
                 mScrollingChild = view;
+                mScrollingChild.Layout.SetPositionByLayout = false;
                 propertyNotification = mScrollingChild?.AddPropertyNotification("position", PropertyCondition.Step(1.0f));
                 propertyNotification.Notified += OnPropertyChanged;
                 mScrollingChild.Relayout += OnScrollingChildRelayout;
@@ -446,6 +447,7 @@ namespace Tizen.NUI.Components
                 mScrollingChild.RemovePropertyNotification(propertyNotification);
                 mScrollingChild.Relayout -= OnScrollingChildRelayout;
 
+                mScrollingChild.Layout.SetPositionByLayout = true;
                 mScrollingChild = new View();
             }
         }
index ab7e1a4..bb20c92 100644 (file)
@@ -22,7 +22,7 @@ namespace Tizen.NUI.Wearable
     /// <summary>
     /// [Draft] This class implements a fish eye layout
     /// </summary>
-    internal class FishEyeLayoutManager : LayoutManager
+    internal class FishEyeLayoutManager : RecycleLayoutManager
     {
         public int CurrentFocusedIndex { get; set; } = 0;
         public int FocusedIndex { get; set; } = 0;
@@ -66,6 +66,12 @@ namespace Tizen.NUI.Wearable
             return (float)(center + result);
         }
 
+
+        public override float CalculateLayoutOrientationSize()
+        {
+            return mStepSize * (DataCount-1);
+        }
+
         public override void Layout(float scrollPosition)
         {
             RecycleItem centerItem = Container.Children[FocusedIndex] as RecycleItem;
@@ -173,6 +179,7 @@ namespace Tizen.NUI.Wearable
                     mStepSize = Container.Children[0].Size.Height / 2.0f + Container.Children[1].Size.Height * Container.Children[1].Scale.X / 2.0f;
                 }
 
+                mStepSize = float.IsNaN(mStepSize)?0:mStepSize;
             }
         }
 
index 0b44afe..e7784a8 100644 (file)
@@ -37,29 +37,44 @@ namespace Tizen.NUI.Wearable
         /// <since_tizen> 8 </since_tizen>
         /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public WearableList(RecycleAdapter adapter) : base(adapter, new FishEyeLayoutManager())
+        public WearableList() : base(new RecycleAdapter(), new FishEyeLayoutManager())
         {
             ScrollingDirection = ScrollableBase.Direction.Vertical;
 
             ScrollDragStartEvent += OnScrollDragStart;
             ScrollAnimationEndEvent += OnAnimationEnd;
 
-            foreach (View child in mContainer.Children)
-            {
-                child.PositionUsesPivotPoint = true;
-                child.ParentOrigin = Tizen.NUI.ParentOrigin.TopCenter;
-            }
-
             mContainer.PositionUsesPivotPoint = true;
             mContainer.ParentOrigin = Tizen.NUI.ParentOrigin.Center;
-            mContainer.PivotPoint = ScrollingDirection == Direction.Vertical ? Tizen.NUI.PivotPoint.TopCenter : Tizen.NUI.PivotPoint.CenterLeft;
-            ScrollAvailableArea = new Vector2( 0,ListLayoutManager.StepSize * (mAdapter.Data.Count - 1) );
-
+            mContainer.PivotPoint = Tizen.NUI.PivotPoint.TopCenter;
             noticeAnimationEndBeforePosition = 50;
 
+            ScrollAvailableArea = new Vector2( 0, mContainer.SizeHeight);
+
             SetFocus(0, false);
         }
 
+        public new RecycleAdapter Adapter
+        {
+            get
+            {
+                return base.Adapter;
+            }
+
+            set
+            {
+                base.Adapter = value;
+
+                foreach (View child in mContainer.Children)
+                {
+                    child.PositionUsesPivotPoint = true;
+                    child.ParentOrigin = Tizen.NUI.ParentOrigin.TopCenter;
+                }
+
+                ScrollAvailableArea = new Vector2( 0, mContainer.SizeHeight );
+            }
+        }
+
         /// <summary>
         /// Set focus to item which has specific data index.
         /// </summary>