1 /* Copyright (c) 2020 Samsung Electronics Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
17 using Tizen.NUI.BaseComponents;
18 using System.Collections.Generic;
19 using System.ComponentModel;
21 namespace Tizen.NUI.Components
24 /// [Draft] This class provides a View that can recycle items to improve performance.
26 /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
27 [EditorBrowsable(EditorBrowsableState.Never)]
28 public class RecyclerView : ScrollableBase
30 protected RecycleAdapter mAdapter;
31 protected View mContainer;
32 protected RecycleLayoutManager mLayoutManager;
33 protected int mTotalItemCount = 15;
34 private List<PropertyNotification> notifications = new List<PropertyNotification>();
38 Initialize(new RecycleAdapter(), new RecycleLayoutManager());
42 /// Default constructor.
44 /// <param name="adapter">Recycle adapter of RecyclerView.</param>
45 /// <param name="layoutManager">Recycle layoutManager of RecyclerView.</param>
46 /// <since_tizen> 8 </since_tizen>
47 /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
48 [EditorBrowsable(EditorBrowsableState.Never)]
49 public RecyclerView(RecycleAdapter adapter, RecycleLayoutManager layoutManager)
51 Initialize(adapter, layoutManager);
54 private void Initialize(RecycleAdapter adapter, RecycleLayoutManager layoutManager)
57 mContainer = new View()
59 WidthSpecification = ScrollingDirection == Direction.Vertical ? LayoutParamPolicies.MatchParent : LayoutParamPolicies.WrapContent,
60 HeightSpecification = ScrollingDirection == Direction.Horizontal ? LayoutParamPolicies.MatchParent : LayoutParamPolicies.WrapContent,
61 Layout = new AbsoluteLayout()
63 SetPositionByLayout = false,
69 ScrollEvent += OnScroll;
72 mAdapter.OnDataChanged += OnAdapterDataChanged;
74 mLayoutManager = layoutManager;
75 mLayoutManager.Container = mContainer;
76 mLayoutManager.ItemSize = mAdapter.CreateRecycleItem().Size;
77 mLayoutManager.DataCount = mAdapter.Data.Count;
82 private void OnItemSizeChanged(object source, PropertyNotification.NotifyEventArgs args)
84 mLayoutManager.Layout(ScrollingDirection == Direction.Horizontal ? mContainer.CurrentPosition.X : mContainer.CurrentPosition.Y);
87 public int TotalItemCount
91 return mTotalItemCount;
95 mTotalItemCount = value;
100 private void InitializeItems()
102 for(int i = mContainer.Children.Count -1 ; i > -1 ; i--)
104 mContainer.Children[i].Unparent();
105 notifications[i].Notified -= OnItemSizeChanged;
106 notifications.RemoveAt(i);
109 for (int i = 0; i < mTotalItemCount; i++)
111 RecycleItem item = mAdapter.CreateRecycleItem();
113 item.Name = "[" + i + "] recycle";
115 if (i < mAdapter.Data.Count)
117 mAdapter.BindData(item);
119 mContainer.Add(item);
121 PropertyNotification noti = item.AddPropertyNotification("size", PropertyCondition.Step(0.1f));
122 noti.Notified += OnItemSizeChanged;
123 notifications.Add(noti);
126 mLayoutManager.Layout(0.0f);
128 if (ScrollingDirection == Direction.Horizontal)
130 mContainer.SizeWidth = mLayoutManager.CalculateLayoutOrientationSize();
134 mContainer.SizeHeight = mLayoutManager.CalculateLayoutOrientationSize();
139 public new Direction ScrollingDirection
143 return base.ScrollingDirection;
147 base.ScrollingDirection = value;
149 if (ScrollingDirection == Direction.Horizontal)
151 mContainer.SizeWidth = mLayoutManager.CalculateLayoutOrientationSize();
155 mContainer.SizeHeight = mLayoutManager.CalculateLayoutOrientationSize();
161 /// Recycler adpater.
163 /// <since_tizen> 8 </since_tizen>
164 /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
165 [EditorBrowsable(EditorBrowsableState.Never)]
166 public RecycleAdapter Adapter
176 mAdapter.OnDataChanged -= OnAdapterDataChanged;
180 mAdapter.OnDataChanged += OnAdapterDataChanged;
181 mLayoutManager.ItemSize = mAdapter.CreateRecycleItem().Size;
182 mLayoutManager.DataCount = mAdapter.Data.Count;
188 /// Recycler layoutManager.
190 /// <since_tizen> 8 </since_tizen>
191 /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
192 [EditorBrowsable(EditorBrowsableState.Never)]
193 public RecycleLayoutManager LayoutManager
197 return mLayoutManager;
201 mLayoutManager = value;
202 mLayoutManager.Container = mContainer;
203 mLayoutManager.ItemSize = mAdapter.CreateRecycleItem().Size;
204 mLayoutManager.DataCount = mAdapter.Data.Count;
209 private void OnScroll(object source, ScrollableBase.ScrollEventArgs args)
211 mLayoutManager.Layout(ScrollingDirection == Direction.Horizontal ? args.Position.X : args.Position.Y);
212 List<RecycleItem> recycledItemList = mLayoutManager.Recycle(ScrollingDirection == Direction.Horizontal ? args.Position.X : args.Position.Y);
213 BindData(recycledItemList);
216 private void OnAdapterDataChanged(object source, EventArgs args)
218 List<RecycleItem> changedData = new List<RecycleItem>();
220 foreach (RecycleItem item in mContainer.Children)
222 changedData.Add(item);
225 BindData(changedData);
228 private void BindData(List<RecycleItem> changedData)
230 foreach (RecycleItem item in changedData)
232 if (item.DataIndex > -1 && item.DataIndex < mAdapter.Data.Count)
235 item.Name = "["+item.DataIndex+"]";
236 mAdapter.BindData(item);
246 /// Adjust scrolling position by own scrolling rules.
247 /// Override this function when developer wants to change destination of flicking.(e.g. always snap to center of item)
249 /// <param name="position">Scroll position which is calculated by ScrollableBase</param>
250 /// <returns>Adjusted scroll destination</returns>
251 /// <since_tizen> 8 </since_tizen>
252 /// This may be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API
253 [EditorBrowsable(EditorBrowsableState.Never)]
254 protected override float AdjustTargetPositionOfScrollAnimation(float position)
256 // Destination is depending on implementation of layout manager.
257 // Get destination from layout manager.
258 return mLayoutManager.CalculateCandidateScrollPosition(position);