}
}
+ private new Extents padding;
/// <summary>
/// overwrite the Padding.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public new Extents Padding
{
- get;
- set;
+ get
+ {
+ if (null == padding)
+ {
+ padding = new Extents((ushort start, ushort end, ushort top, ushort bottom) =>
+ {
+ padding.Start = start;
+ padding.End = end;
+ padding.Top = top;
+ padding.Bottom = bottom;
+ }, 0, 0, 0, 0);
+ }
+
+ return padding;
+ }
+ set
+ {
+ if (null == padding)
+ {
+ padding = new Extents((ushort start, ushort end, ushort top, ushort bottom) =>
+ {
+ padding.Start = start;
+ padding.End = end;
+ padding.Top = top;
+ padding.Bottom = bottom;
+ }, 0, 0, 0, 0);
+ }
+
+ padding.CopyFrom(value);
+ }
}
/// <summary>
{
if (mLayout != null)
{
- mLayout.StopScroll();
+ mLayout.StopScroll(false);
}
if (mAdapter != null)
/// you can override it to create your own default attributes.
/// </summary>
/// <since_tizen> 6 </since_tizen>
- /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
+ /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
- protected override Attributes GetAttributes()
+ protected override ViewStyle GetViewStyle()
{
return null;
}
{
offset = range - extent;
}
+ if (offset < 0)
+ {
+ offset = 0;
+ }
if (mScrollBar.Direction == ScrollBar.DirectionType.Vertical)
{
- mScrollBar.ThumbSize = new Size(thickness, length);
+ mScrollBar.Style.Thumb.Size = new Size(thickness, length);
}
else
{
- mScrollBar.ThumbSize = new Size(length, thickness);
+ mScrollBar.Style.Thumb.Size = new Size(length, thickness);
}
mScrollBar.MinValue = 0;
mScrollBar.MaxValue = (int)(range - extent);
{
if (e.PanGesture.State == Gesture.StateType.Started)
{
- mLayout.StopScroll();
+ mLayout.StopScroll(true);
}
else if (e.PanGesture.State == Gesture.StateType.Continuing)
{
Down
}
+ private readonly int SCROLL_ANIMATION_DURATION = 500;
+
private FlexibleView mFlexibleView;
private ChildHelper mChildHelper;
return;
}
- if (mScrollAni == null)
- {
- mScrollAni = new Animation();
- mScrollAni.Finished += OnScrollAnimationFinished;
- }
- else if (mScrollAni.State == Animation.States.Playing)
+ if (dx == 0)
{
- //StopScroll();
- mScrollAni.Stop(Animation.EndActions.StopFinal);
+ return;
}
- mScrollAni.Duration = 500;
- mScrollAni.DefaultAlphaFunction = new AlphaFunction(AlphaFunction.BuiltinFunctions.EaseOutSquare);
-
- mScrollAni.Clear();
int childCount = mChildHelper.GetChildCount();
if (immediate == true)
}
else
{
+ if (mScrollAni == null)
+ {
+ mScrollAni = new Animation();
+ mScrollAni.Duration = SCROLL_ANIMATION_DURATION;
+ mScrollAni.DefaultAlphaFunction = new AlphaFunction(AlphaFunction.BuiltinFunctions.EaseOutSquare);
+ }
+
+ // avoid out of boundary of flexibleview. delta value might be used for shadow.
+ // this must be done before animation clear.
+ if (childCount > 0)
+ {
+ ViewHolder vh = mChildHelper.GetChildAt(0);
+ if (vh.LayoutPosition == 0)
+ {
+ if ((int)(vh.Left + dx) > 0)
+ {
+ dx = 0 - vh.Left;
+ }
+ }
+
+ vh = mChildHelper.GetChildAt(childCount - 1);
+ if (vh.LayoutPosition == ItemCount - 1)
+ {
+ if ((int)(vh.Right + dx) < (int)Width + PaddingRight)
+ {
+ dx = Width + PaddingRight - vh.Right;
+ }
+ }
+ }
+
+ // save position before animation clear.
+ float[] childrenPositon = new float[childCount];
for (int i = childCount - 1; i >= 0; i--)
{
ViewHolder v = mChildHelper.GetChildAt(i);
+ childrenPositon[i] = v.ItemView.PositionX;
+ }
+
+ mScrollAni.Clear();
+ mScrollAni.Finished += OnScrollAnimationFinished;
+
+ for (int i = childCount - 1; i >= 0; i--)
+ {
+ ViewHolder v = mChildHelper.GetChildAt(i);
+ // set position again because position might be changed after animation clear.
+ v.ItemView.PositionX = childrenPositon[i];
mScrollAni.AnimateTo(v.ItemView, "PositionX", v.ItemView.PositionX + dx);
}
mScrollAni.Play();
return;
}
- if (mScrollAni == null)
- {
- mScrollAni = new Animation();
- mScrollAni.Finished += OnScrollAnimationFinished;
- }
- else if (mScrollAni.State == Animation.States.Playing)
+ if (dy == 0)
{
- //StopScroll();
- mScrollAni.Stop(Animation.EndActions.StopFinal);
+ return;
}
- mScrollAni.Duration = 500;
- mScrollAni.DefaultAlphaFunction = new AlphaFunction(AlphaFunction.BuiltinFunctions.EaseOutSquare);
-
- mScrollAni.Clear();
int childCount = mChildHelper.GetChildCount();
if (immediate == true)
}
else
{
+ if (mScrollAni == null)
+ {
+ mScrollAni = new Animation();
+ mScrollAni.Duration = SCROLL_ANIMATION_DURATION;
+ mScrollAni.DefaultAlphaFunction = new AlphaFunction(AlphaFunction.BuiltinFunctions.EaseOutSquare);
+ }
+
+ // avoid out of boundary of flexibleview. delta value might be used for shadow.
+ // this must be done before animation clear.
+ if (childCount > 0)
+ {
+ ViewHolder vh = mChildHelper.GetChildAt(0);
+ if (vh.LayoutPosition == 0)
+ {
+ if ((int)(vh.Top + dy) > 0)
+ {
+ dy = 0 - vh.Top;
+ }
+ }
+
+ vh = mChildHelper.GetChildAt(childCount - 1);
+ if (vh.LayoutPosition == ItemCount - 1)
+ {
+ if ((int)(vh.Bottom + dy) < (int)Height + PaddingBottom)
+ {
+ dy = Height + PaddingBottom - vh.Bottom;
+ }
+ }
+ }
+
+ // save position before animation clear.
+ float[] childPositon = new float[childCount];
+ for (int i = childCount - 1; i >= 0; i--)
+ {
+ ViewHolder v = mChildHelper.GetChildAt(i);
+ childPositon[i] = v.ItemView.PositionY;
+ }
+
+ mScrollAni.Clear();
+ mScrollAni.Finished += OnScrollAnimationFinished;
+
for (int i = childCount - 1; i >= 0; i--)
{
ViewHolder v = mChildHelper.GetChildAt(i);
+ // set position again because position might be changed after animation clear.
+ v.ItemView.PositionY = childPositon[i];
mScrollAni.AnimateTo(v.ItemView, "PositionY", v.ItemView.PositionY + dy);
}
mScrollAni.Play();
[EditorBrowsable(EditorBrowsableState.Never)]
protected abstract int GetNextPosition(int position, FlexibleView.LayoutManager.Direction direction);
+ /// <summary>
+ /// Retrieves the first visible item view.
+ /// </summary>
+ /// <since_tizen> 6 </since_tizen>
+ /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected virtual ViewHolder FindFirstVisibleItemView()
+ {
+ return null;
+ }
+
+ /// <summary>
+ /// Retrieves the last visible item view.
+ /// </summary>
+ /// <since_tizen> 6 </since_tizen>
+ /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected virtual ViewHolder FindLastVisibleItemView()
+ {
+ return null;
+ }
+
internal virtual ViewHolder OnFocusSearchFailed(FlexibleView.ViewHolder focused, LayoutManager.Direction direction, Recycler recycler)
{
return null;
mChildHelper = recyclerView.mChildHelper;
}
- internal void StopScroll()
+ internal void StopScroll(bool doSomethingAfterAnimationStopped)
{
if (mScrollAni != null && mScrollAni.State == Animation.States.Playing)
{
- mScrollAni.Stop(Animation.EndActions.StopFinal);
- mScrollAni.Clear();
- OnScrollAnimationFinished(mScrollAni, null);
+ mScrollAni.Finished -= OnScrollAnimationFinished;
+ mScrollAni.Stop();
+
+ if (doSomethingAfterAnimationStopped)
+ {
+ OnScrollAnimationFinished(mScrollAni, null);
+ }
}
}
private void OnScrollAnimationFinished(object sender, EventArgs e)
{
- RecycleChildrenInt(mFlexibleView.mRecycler);
+ foreach (ViewHolder holder in mPendingRecycleViews)
+ {
+ holder.PendingRecycle = false;
+ }
+ mPendingRecycleViews.Clear();
+
+ int start = NO_POSITION;
+ ViewHolder firstItemView = FindFirstVisibleItemView();
+ if (firstItemView != null)
+ start = firstItemView.LayoutPosition;
+ else
+ start = 0;
+
+ int itemCount = ChildCount;
+
+ int end = NO_POSITION;
+ ViewHolder lastItemView = FindLastVisibleItemView();
+ if (lastItemView != null)
+ end = lastItemView.LayoutPosition;
+ else
+ end = itemCount - 1;
+
+ List<ViewHolder> removedViewList = new List<ViewHolder>();
+ for (int i = 0; i < itemCount; i++)
+ {
+ ViewHolder v = GetChildAt(i);
+
+ //if item view of holder is visible, it should not be recycled.
+ if (v.LayoutPosition >= start && v.LayoutPosition <= end)
+ continue;
+
+ removedViewList.Add(v);
+ }
+
+ for (int i = 0; i < removedViewList.Count; i++)
+ {
+ ViewHolder v = removedViewList[i];
+ v.PendingRecycle = false;
+ mFlexibleView.mRecycler.RecycleView(v);
+ mChildHelper.RemoveView(v);
+ }
+
+ // relayout
}
private void AddViewInternal(ViewHolder holder, int index, bool disappearing)