{
return scrollPosition;
}
+
+ public override View RequestNextFocusableView(View currentFocusedView, View.FocusDirection direction, bool loopEnabled)
+ {
+ View nextFocusedView = null;
+ int targetSibling = -1;
+ bool isHorizontal = LayoutOrientation == Orientation.Horizontal;
+
+ switch(direction)
+ {
+ case View.FocusDirection.Left :
+ {
+ targetSibling = isHorizontal ? currentFocusedView.SiblingOrder - 1 : currentFocusedView.SiblingOrder - Rows;
+ break;
+ }
+ case View.FocusDirection.Right :
+ {
+ targetSibling = isHorizontal ? currentFocusedView.SiblingOrder + 1 : currentFocusedView.SiblingOrder + Rows;
+ break;
+ }
+ case View.FocusDirection.Up :
+ {
+ targetSibling = isHorizontal ? currentFocusedView.SiblingOrder - Columns : currentFocusedView.SiblingOrder - 1;
+ break;
+ }
+ case View.FocusDirection.Down :
+ {
+ targetSibling = isHorizontal ? currentFocusedView.SiblingOrder + Columns : currentFocusedView.SiblingOrder + 1;
+ break;
+ }
+ }
+
+ if(targetSibling > -1 && targetSibling < Container.Children.Count)
+ {
+ RecycleItem candidate = Container.Children[targetSibling] as RecycleItem;
+ if(candidate.DataIndex >= 0 && candidate.DataIndex < DataCount)
+ {
+ nextFocusedView = candidate;
+ }
+ }
+
+ return nextFocusedView;
+ }
}
}
\ No newline at end of file
{
return scrollPosition;
}
+
+ public override View RequestNextFocusableView(View currentFocusedView, View.FocusDirection direction, bool loopEnabled)
+ {
+ View nextFocusedView = null;
+ int targetSibling = -1;
+ bool isHorizontal = LayoutOrientation == Orientation.Horizontal;
+
+ switch(direction)
+ {
+ case View.FocusDirection.Left :
+ {
+ targetSibling = isHorizontal ? currentFocusedView.SiblingOrder - 1 : targetSibling;
+ break;
+ }
+ case View.FocusDirection.Right :
+ {
+ targetSibling = isHorizontal ? currentFocusedView.SiblingOrder + 1 : targetSibling;
+ break;
+ }
+ case View.FocusDirection.Up :
+ {
+ targetSibling = isHorizontal ? targetSibling : currentFocusedView.SiblingOrder - 1;
+ break;
+ }
+ case View.FocusDirection.Down :
+ {
+ targetSibling = isHorizontal ? targetSibling : currentFocusedView.SiblingOrder + 1;
+ break;
+ }
+ }
+
+ if(targetSibling > -1 && targetSibling < Container.Children.Count)
+ {
+ RecycleItem candidate = Container.Children[targetSibling] as RecycleItem;
+ if(candidate.DataIndex >= 0 && candidate.DataIndex < DataCount)
+ {
+ nextFocusedView = candidate;
+ }
+ }
+
+ return nextFocusedView;
+ }
}
}
private void Initialize(RecycleAdapter adapter, RecycleLayoutManager layoutManager)
{
+ FocusGroup = true;
+ SetKeyboardNavigationSupport(true);
Scrolling += OnScrolling;
this.adapter = adapter;
{
layoutManager.Layout(ScrollingDirection == Direction.Horizontal ? ContentContainer.CurrentPosition.X : ContentContainer.CurrentPosition.Y);
}
-
- public int TotalItemCount
+
+ public int TotalItemCount
{
get
{
private void InitializeItems()
{
- for(int i = Children.Count -1 ; i > -1 ; i--)
+ for (int i = Children.Count - 1; i > -1; i--)
{
Children[i].Unparent();
notifications[i].Notified -= OnItemSizeChanged;
if (item.DataIndex > -1 && item.DataIndex < adapter.Data.Count)
{
item.Show();
- item.Name = "["+item.DataIndex+"]";
+ item.Name = "[" + item.DataIndex + "]";
adapter.BindData(item);
}
else
// Get destination from layout manager.
return layoutManager.CalculateCandidateScrollPosition(position);
}
+
+ private View focusedView;
+ private int prevFocusedDataIndex = 0;
+
+ public override View GetNextFocusableView(View currentFocusedView, View.FocusDirection direction, bool loopEnabled)
+ {
+ View nextFocusedView = null;
+
+ if (!focusedView)
+ {
+ // If focusedView is null, find child which has previous data index
+ if (Children.Count > 0 && Adapter.Data.Count > 0)
+ {
+ for (int i = 0; i < Children.Count; i++)
+ {
+ RecycleItem item = Children[i] as RecycleItem;
+ if (item.DataIndex == prevFocusedDataIndex)
+ {
+ nextFocusedView = item;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ // If this is not first focus, request next focus to LayoutManager
+ nextFocusedView = LayoutManager.RequestNextFocusableView(currentFocusedView, direction, loopEnabled);
+ }
+
+ if (nextFocusedView)
+ {
+ // Check next focused view is inside of visible area.
+ // If it is not, move scroll position to make it visible.
+ Position scrollPosition = ContentContainer.CurrentPosition;
+ float targetPosition = -(ScrollingDirection == Direction.Horizontal ? scrollPosition.X : scrollPosition.Y);
+
+ float left = nextFocusedView.Position.X;
+ float right = nextFocusedView.Position.X + nextFocusedView.Size.Width;
+ float top = nextFocusedView.Position.Y;
+ float bottom = nextFocusedView.Position.Y + nextFocusedView.Size.Height;
+
+ float visibleRectangleLeft = -scrollPosition.X;
+ float visibleRectangleRight = -scrollPosition.X + Size.Width;
+ float visibleRectangleTop = -scrollPosition.Y;
+ float visibleRectangleBottom = -scrollPosition.Y + Size.Height;
+
+ if (ScrollingDirection == Direction.Horizontal)
+ {
+ if ((direction == View.FocusDirection.Left || direction == View.FocusDirection.Up) && left < visibleRectangleLeft)
+ {
+ targetPosition = left;
+ }
+ else if ((direction == View.FocusDirection.Right || direction == View.FocusDirection.Down) && right > visibleRectangleRight)
+ {
+ targetPosition = right - Size.Width;
+ }
+ }
+ else
+ {
+ if ((direction == View.FocusDirection.Up || direction == View.FocusDirection.Left) && top < visibleRectangleTop)
+ {
+ targetPosition = top;
+ }
+ else if ((direction == View.FocusDirection.Down || direction == View.FocusDirection.Right) && bottom > visibleRectangleBottom)
+ {
+ targetPosition = bottom - Size.Height;
+ }
+ }
+
+ focusedView = nextFocusedView;
+ prevFocusedDataIndex = (nextFocusedView as RecycleItem).DataIndex;
+
+ ScrollTo(targetPosition, true);
+ }
+ else
+ {
+ // If nextView is null, it means that we should move focus to outside of Control.
+ // Return FocusableView depending on direction.
+ switch (direction)
+ {
+ case View.FocusDirection.Left:
+ {
+ nextFocusedView = LeftFocusableView;
+ break;
+ }
+ case View.FocusDirection.Right:
+ {
+ nextFocusedView = RightFocusableView;
+ break;
+ }
+ case View.FocusDirection.Up:
+ {
+ nextFocusedView = UpFocusableView;
+ break;
+ }
+ case View.FocusDirection.Down:
+ {
+ nextFocusedView = DownFocusableView;
+ break;
+ }
+ }
+
+ if(nextFocusedView)
+ {
+ focusedView = null;
+ }
+ else
+ {
+ //If FocusableView doesn't exist, not move focus.
+ nextFocusedView = focusedView;
+ }
+ }
+
+ return nextFocusedView;
+ }
}
}