2 * Copyright(c) 2018 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 using System.Runtime.InteropServices;
20 using Tizen.NUI.BaseComponents;
21 using System.ComponentModel;
26 /// Provides the functionality of handling keyboard navigation and maintaining the two-dimensional keyboard focus chain.<br />
27 /// It provides functionality of setting the focus and moving the focus in four directions( i.e., left, right, up, and down).<br />
28 /// It also draws a highlight for the focused view and sends an event when the focus is changed.<br />
30 /// <since_tizen> 3 </since_tizen>
31 public class FocusManager : BaseHandle
33 private static readonly FocusManager instance = FocusManager.Get();
34 private global::System.Runtime.InteropServices.HandleRef swigCPtr;
35 private CustomAlgorithmInterfaceWrapper _customAlgorithmInterfaceWrapper;
37 private EventHandlerWithReturnType<object, PreFocusChangeEventArgs, View> _preFocusChangeEventHandler;
38 private PreFocusChangeEventCallback _preFocusChangeCallback;
40 private EventHandler<FocusChangedEventArgs> _focusChangedEventHandler;
41 private FocusChangedEventCallback _focusChangedEventCallback;
43 private EventHandler<FocusGroupChangedEventArgs> _focusGroupChangedEventHandler;
44 private FocusGroupChangedEventCallback _focusGroupChangedEventCallback;
46 private EventHandler<FocusedViewActivatedEventArgs> _focusedViewEnterKeyEventHandler;
47 private FocusedViewEnterKeyEventCallback _focusedViewEnterKeyEventCallback;
49 private EventHandler<FocusedViewActivatedEventArgs> _focusedViewEnterKeyEventHandler2;
50 private FocusedViewEnterKeyEventCallback2 _focusedViewEnterKeyEventCallback2;
52 internal FocusManager(global::System.IntPtr cPtr, bool cMemoryOwn) : base(NDalicManualPINVOKE.FocusManager_SWIGUpcast(cPtr), cMemoryOwn)
54 swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
57 internal FocusManager() : this(NDalicManualPINVOKE.new_FocusManager(), true)
59 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
62 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
63 internal delegate IntPtr PreFocusChangeEventCallback(IntPtr current, IntPtr proposed, View.FocusDirection direction);
65 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
66 internal delegate void FocusChangedEventCallback(IntPtr current, IntPtr next);
68 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
69 private delegate void FocusGroupChangedEventCallback(IntPtr current, bool forwardDirection);
71 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
72 private delegate void FocusedViewEnterKeyEventCallback(IntPtr view);
74 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
75 private delegate void FocusedViewEnterKeyEventCallback2(IntPtr view);
78 /// PreFocusChange will be triggered before the focus is going to be changed.<br />
79 /// The FocusManager makes the best guess for which view to focus towards the given direction, but applications might want to change that.<br />
80 /// By connecting with this event, they can check the proposed view to focus and return a different view if they wish.<br />
81 /// This event is only triggered when the navigation key is pressed and KeyboardFocusManager tries to move the focus automatically.<br />
82 /// It won't be emitted for focus movement by calling the SetCurrentFocusView directly.<br />
84 /// <since_tizen> 3 </since_tizen>
85 public event EventHandlerWithReturnType<object, PreFocusChangeEventArgs, View> PreFocusChange
89 if (_preFocusChangeEventHandler == null)
91 _preFocusChangeCallback = OnPreFocusChange;
92 PreFocusChangeSignal().Connect(_preFocusChangeCallback);
94 _preFocusChangeEventHandler += value;
98 _preFocusChangeEventHandler -= value;
99 if (_preFocusChangeEventHandler == null && PreFocusChangeSignal().Empty() == false)
101 PreFocusChangeSignal().Disconnect(_preFocusChangeCallback);
107 /// The FocusGroupChanged will be triggered after the current focused view has been changed.
109 /// <since_tizen> 3 </since_tizen>
110 public event EventHandler<FocusChangedEventArgs> FocusChanged
114 if (_focusChangedEventCallback == null)
116 _focusChangedEventCallback = OnFocusChanged;
117 FocusChangedSignal().Connect(_focusChangedEventCallback);
119 _focusChangedEventHandler += value;
123 _focusChangedEventHandler -= value;
125 if (_focusChangedEventCallback == null && FocusChangedSignal().Empty() == false)
127 FocusChangedSignal().Disconnect(_focusChangedEventCallback);
133 /// The FocusGroupChanged will be triggered when the focus group has been changed.<br />
134 /// If the current focus group has a parent layout control, the FocusManager will make the best guess for the next focus group to move the focus to in the given direction (forward or backward).<br />
135 /// If not, the application has to set the new focus.<br />
137 /// <since_tizen> 3 </since_tizen>
138 public event EventHandler<FocusGroupChangedEventArgs> FocusGroupChanged
142 if (_focusGroupChangedEventCallback == null)
144 _focusGroupChangedEventCallback = OnFocusGroupChanged;
145 FocusGroupChangedSignal().Connect(_focusGroupChangedEventCallback);
147 _focusGroupChangedEventHandler += value;
151 _focusGroupChangedEventHandler -= value;
153 if (_focusGroupChangedEventCallback == null && FocusGroupChangedSignal().Empty() == false)
155 FocusGroupChangedSignal().Disconnect(_focusGroupChangedEventCallback);
161 /// The FocusedViewActivated will be triggered when the current focused view has the enter key pressed on it.
163 /// <since_tizen> 3 </since_tizen>
164 public event EventHandler<FocusedViewActivatedEventArgs> FocusedViewActivated
168 if (_focusedViewEnterKeyEventCallback == null)
170 _focusedViewEnterKeyEventCallback = OnFocusedViewEnterKey;
171 FocusedViewEnterKeySignal().Connect(_focusedViewEnterKeyEventCallback);
173 _focusedViewEnterKeyEventHandler += value;
177 _focusedViewEnterKeyEventHandler -= value;
179 if (_focusedViewEnterKeyEventCallback != null && FocusedViewEnterKeySignal().Empty() == false)
181 FocusedViewEnterKeySignal().Disconnect(_focusedViewEnterKeyEventCallback);
187 /// [Obsolete("Please do not use! this will be deprecated")]
189 /// <since_tizen> 3 </since_tizen>
190 /// Please do not use! this will be deprecated!
191 /// Instead please use FocusedViewActivated.
192 [Obsolete("Please do not use! This will be deprecated! Please use FocusManager.FocusedViewActivated instead! " +
194 "FocusManager.Instance.FocusedViewActivated = OnFocusedViewActivated; " +
195 "private void OnFocusedViewActivated(object source, FocusManager.FocusedViewActivatedEventArgs args) {...}")]
196 [EditorBrowsable(EditorBrowsableState.Never)]
197 public event EventHandler<FocusedViewActivatedEventArgs> FocusedViewEnterKeyPressed
201 if (_focusedViewEnterKeyEventCallback2 == null)
203 _focusedViewEnterKeyEventCallback2 = OnFocusedViewEnterKey2;
204 FocusedViewEnterKeySignal().Connect(_focusedViewEnterKeyEventCallback2);
206 _focusedViewEnterKeyEventHandler2 += value;
210 _focusedViewEnterKeyEventHandler2 -= value;
212 if (_focusedViewEnterKeyEventCallback2 != null && FocusedViewEnterKeySignal().Empty() == false)
214 FocusedViewEnterKeySignal().Disconnect(_focusedViewEnterKeyEventCallback2);
220 /// ICustomFocusAlgorithm is used to provide the custom keyboard focus algorithm for retrieving the next focusable view.<br />
221 /// The application can implement the interface and override the keyboard focus behavior.<br />
222 /// If the focus is changing within a layout container, then the layout container is queried first to provide the next focusable view.<br />
223 /// If this does not provide a valid view, then the Keyboard FocusManager will check focusable properties to determine the next focusable actor.<br />
224 /// If focusable properties are not set, then the keyboard FocusManager calls the GetNextFocusableView() method of this interface.<br />
226 /// <since_tizen> 3 </since_tizen>
227 public interface ICustomFocusAlgorithm
230 /// Get the next focus actor.
232 /// <param name="current">The current focus view.</param>
233 /// <param name="proposed">The proposed focus view</param>
234 /// <param name="direction">The focus move direction</param>
235 /// <returns>The next focus actor.</returns>
236 /// <since_tizen> 3 </since_tizen>
237 View GetNextFocusableView(View current, View proposed, View.FocusDirection direction);
241 /// Gets or sets the status of whether the focus movement should be looped within the same focus group.<br />
242 /// The focus movement is not looped by default.<br />
244 /// <since_tizen> 3 </since_tizen>
245 public bool FocusGroupLoop
249 SetFocusGroupLoop(value);
253 return GetFocusGroupLoop();
258 /// Gets or sets the focus indicator view.<br />
259 /// This will replace the default focus indicator view in the FocusManager and will be added to the focused view as a highlight.<br />
261 /// <since_tizen> 3 </since_tizen>
262 public View FocusIndicator
266 SetFocusIndicatorView(value);
270 return GetFocusIndicatorView();
275 /// Gets the singleton of the FocusManager object.
277 /// <since_tizen> 3 </since_tizen>
278 public static FocusManager Instance
287 /// Moves the keyboard focus to the given view.<br />
288 /// Only one view can be focused at the same time.<br />
289 /// The view must be in the stage already and keyboard focusable.<br />
291 /// <param name="view">The view to be focused.</param>
292 /// <returns>Whether the focus is successful or not.</returns>
293 /// <since_tizen> 3 </since_tizen>
294 public bool SetCurrentFocusView(View view)
298 throw new ArgumentNullException("the target view should not be null");
301 bool ret = NDalicManualPINVOKE.FocusManager_SetCurrentFocusActor(swigCPtr, View.getCPtr(view));
302 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
307 /// Gets the current focused view.
309 /// <returns>A handle to the current focused view or an empty handle if no view is focused.</returns>
310 /// <since_tizen> 3 </since_tizen>
311 public View GetCurrentFocusView()
313 //to fix memory leak issue, match the handle count with native side.
314 IntPtr cPtr = NDalicManualPINVOKE.FocusManager_GetCurrentFocusActor(swigCPtr);
315 HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
316 View ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as View;
317 NDalicPINVOKE.delete_BaseHandle(CPtr);
318 CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
324 /// Moves the focus to the next focusable view in the focus chain in the given direction (according to the focus traversal order).
326 /// <param name="direction">The direction of the focus movement.</param>
327 /// <returns>True if the movement was successful.</returns>
328 /// <since_tizen> 3 </since_tizen>
329 public bool MoveFocus(View.FocusDirection direction)
331 bool ret = NDalicManualPINVOKE.FocusManager_MoveFocus(swigCPtr, (int)direction);
332 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
337 /// Clears the focus from the current focused view if any, so that no view is focused in the focus chain.<br />
338 /// It will emit the FocusChanged event without the current focused view.<br />
340 /// <since_tizen> 3 </since_tizen>
341 public void ClearFocus()
343 NDalicManualPINVOKE.FocusManager_ClearFocus(swigCPtr);
344 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
348 /// Move the focus to previous focused view.
350 /// <since_tizen> 3 </since_tizen>
351 public void MoveFocusBackward()
353 NDalicManualPINVOKE.FocusManager_MoveFocusBackward(swigCPtr);
354 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
358 /// Sets whether the view is a focus group that can limit the scope of the focus movement to its child views in the focus chain.<br />
359 /// Layout controls set themselves as focus groups by default.<br />
361 /// <param name="view">The view to be set as a focus group.</param>
362 /// <param name="isFocusGroup">Whether to set the view as a focus group or not.</param>
363 /// <since_tizen> 3 </since_tizen>
364 public void SetAsFocusGroup(View view, bool isFocusGroup)
366 NDalicManualPINVOKE.FocusManager_SetAsFocusGroup(swigCPtr, View.getCPtr(view), isFocusGroup);
367 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
371 /// Checks whether the view is set as a focus group or not.
373 /// <param name="view">The view to be checked.</param>
374 /// <returns>Whether the view is set as a focus group.</returns>
375 /// <since_tizen> 3 </since_tizen>
376 public bool IsFocusGroup(View view)
378 bool ret = NDalicManualPINVOKE.FocusManager_IsFocusGroup(swigCPtr, View.getCPtr(view));
379 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
384 /// Returns the closest ancestor of the given view that is a focus group.
386 /// <param name="view">The view to be checked for its focus group.</param>
387 /// <returns>The focus group the given view belongs to or an empty handle if the given view.</returns>
388 /// <since_tizen> 3 </since_tizen>
389 public View GetFocusGroup(View view)
391 //to fix memory leak issue, match the handle count with native side.
392 IntPtr cPtr = NDalicManualPINVOKE.FocusManager_GetFocusGroup(swigCPtr, View.getCPtr(view));
393 HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
394 View ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as View;
395 NDalicPINVOKE.delete_BaseHandle(CPtr);
396 CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
402 /// Provides the implementation of a custom focus algorithm interface to allow the application to define the focus logic.<br />
404 /// <param name="arg0">The user's implementation of ICustomFocusAlgorithm.</param>
405 /// <since_tizen> 3 </since_tizen>
406 public void SetCustomAlgorithm(ICustomFocusAlgorithm arg0)
408 _customAlgorithmInterfaceWrapper = new CustomAlgorithmInterfaceWrapper();
409 _customAlgorithmInterfaceWrapper.SetFocusAlgorithm(arg0);
411 NDalicPINVOKE.SetCustomAlgorithm(swigCPtr, CustomAlgorithmInterface.getCPtr(_customAlgorithmInterfaceWrapper));
412 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
415 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(FocusManager obj)
417 return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
420 internal static FocusManager Get()
422 FocusManager ret = new FocusManager(NDalicManualPINVOKE.FocusManager_Get(), true);
423 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
427 internal void SetFocusGroupLoop(bool enabled)
429 NDalicManualPINVOKE.FocusManager_SetFocusGroupLoop(swigCPtr, enabled);
430 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
433 internal bool GetFocusGroupLoop()
435 bool ret = NDalicManualPINVOKE.FocusManager_GetFocusGroupLoop(swigCPtr);
436 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
440 internal void SetFocusIndicatorView(View indicator)
442 NDalicManualPINVOKE.FocusManager_SetFocusIndicatorActor(swigCPtr, View.getCPtr(indicator));
443 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
446 internal View GetFocusIndicatorView()
448 //to fix memory leak issue, match the handle count with native side.
449 IntPtr cPtr = NDalicManualPINVOKE.FocusManager_GetFocusIndicatorActor(swigCPtr);
450 HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
451 View ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as View;
452 NDalicPINVOKE.delete_BaseHandle(CPtr);
453 CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
458 internal PreFocusChangeSignal PreFocusChangeSignal()
460 PreFocusChangeSignal ret = new PreFocusChangeSignal(NDalicManualPINVOKE.FocusManager_PreFocusChangeSignal(swigCPtr), false);
461 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
465 internal FocusChangedSignal FocusChangedSignal()
467 FocusChangedSignal ret = new FocusChangedSignal(NDalicManualPINVOKE.FocusManager_FocusChangedSignal(swigCPtr), false);
468 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
472 internal FocusGroupChangedSignal FocusGroupChangedSignal()
474 FocusGroupChangedSignal ret = new FocusGroupChangedSignal(NDalicManualPINVOKE.FocusManager_FocusGroupChangedSignal(swigCPtr), false);
475 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
479 internal ViewSignal FocusedViewEnterKeySignal()
481 ViewSignal ret = new ViewSignal(NDalicManualPINVOKE.FocusManager_FocusedActorEnterKeySignal(swigCPtr), false);
482 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
486 private IntPtr OnPreFocusChange(IntPtr current, IntPtr proposed, View.FocusDirection direction)
489 PreFocusChangeEventArgs e = new PreFocusChangeEventArgs();
491 if (current != global::System.IntPtr.Zero)
493 e.CurrentView = Registry.GetManagedBaseHandleFromNativePtr(current) as View;
495 if (proposed != global::System.IntPtr.Zero)
497 e.ProposedView = Registry.GetManagedBaseHandleFromNativePtr(proposed) as View;
499 e.Direction = direction;
501 if (_preFocusChangeEventHandler != null)
503 view = _preFocusChangeEventHandler(this, e);
508 return view.GetPtrfromView();
512 if (e.ProposedView) return proposed;
517 private void OnFocusChanged(IntPtr current, IntPtr next)
519 FocusChangedEventArgs e = new FocusChangedEventArgs();
521 e.CurrentView = Registry.GetManagedBaseHandleFromNativePtr(current) as View;
522 e.NextView = Registry.GetManagedBaseHandleFromNativePtr(next) as View;
524 if (_focusChangedEventHandler != null)
526 _focusChangedEventHandler(this, e);
530 private void OnFocusGroupChanged(IntPtr current, bool forwardDirection)
532 FocusGroupChangedEventArgs e = new FocusGroupChangedEventArgs();
534 e.CurrentView = Registry.GetManagedBaseHandleFromNativePtr(current) as View;
535 e.ForwardDirection = forwardDirection;
537 if (_focusGroupChangedEventHandler != null)
539 _focusGroupChangedEventHandler(this, e);
543 private void OnFocusedViewEnterKey(IntPtr view)
545 FocusedViewActivatedEventArgs e = new FocusedViewActivatedEventArgs();
547 e.View = Registry.GetManagedBaseHandleFromNativePtr(view) as View;
549 if (_focusedViewEnterKeyEventHandler != null)
551 _focusedViewEnterKeyEventHandler(this, e);
556 /// Please do not use! this will be deprecated!
558 /// Please do not use! this will be deprecated!
559 /// Instead please use OnFocusedViewEnterKey.
560 [Obsolete("Please do not use! This will be deprecated! Please use FocusManager.OnFocusedViewEnterKey instead!")]
561 [EditorBrowsable(EditorBrowsableState.Never)]
562 private void OnFocusedViewEnterKey2(IntPtr view)
564 FocusedViewActivatedEventArgs e = new FocusedViewActivatedEventArgs();
566 e.View = Registry.GetManagedBaseHandleFromNativePtr(view) as View;
568 if (_focusedViewEnterKeyEventHandler != null)
570 _focusedViewEnterKeyEventHandler(this, e);
575 /// Event arguments that passed via the PreFocusChange signal.
577 /// <since_tizen> 3 </since_tizen>
578 public class PreFocusChangeEventArgs : EventArgs
580 private View _current;
581 private View _proposed;
582 private View.FocusDirection _direction;
585 /// The current focus view.
587 /// <since_tizen> 3 </since_tizen>
588 public View CurrentView
601 /// The proposed view.
603 /// <since_tizen> 3 </since_tizen>
604 public View ProposedView
617 /// The focus move direction.
619 /// <since_tizen> 3 </since_tizen>
620 public View.FocusDirection Direction
634 /// Event arguments that passed via the FocusChanged signal.
636 /// <since_tizen> 3 </since_tizen>
637 public class FocusChangedEventArgs : EventArgs
639 private View _current;
643 /// The current focus view.
645 /// <since_tizen> 3 </since_tizen>
646 public View CurrentView
658 /// The next focus view.
660 /// <since_tizen> 3 </since_tizen>
675 /// Event arguments that passed via the FocusGroupChanged signal.
677 /// <since_tizen> 3 </since_tizen>
678 public class FocusGroupChangedEventArgs : EventArgs
680 private View _current;
681 private bool _forwardDirection;
684 /// The current focus view.
686 /// <since_tizen> 3 </since_tizen>
687 public View CurrentView
700 /// The forward direction.
702 /// <since_tizen> 3 </since_tizen>
703 public bool ForwardDirection
707 return _forwardDirection;
711 _forwardDirection = value;
717 /// Event arguments that passed via the FocusedViewEnterKey signal.
719 /// <since_tizen> 3 </since_tizen>
720 public class FocusedViewActivatedEventArgs : EventArgs
727 /// <since_tizen> 3 </since_tizen>
742 /// Please do not use! this will be deprecated
744 /// <since_tizen> 3 </since_tizen>
745 /// Please do not use! this will be deprecated.
746 /// Instead please use FocusedViewActivatedEventArgs.
747 [Obsolete("Please do not use! This will be deprecated! Please use FocusedViewActivatedEventArgs instead! " +
749 "FocusManager.Instance.FocusedViewActivated = OnFocusedViewActivated; " +
750 "private void OnFocusedViewActivated(object source, FocusManager.FocusedViewActivatedEventArgs arg)" +
752 [EditorBrowsable(EditorBrowsableState.Never)]
753 public class FocusedViewEnterKeyEventArgs : EventArgs
760 /// <since_tizen> 3 </since_tizen>
774 private class CustomAlgorithmInterfaceWrapper : CustomAlgorithmInterface
776 private FocusManager.ICustomFocusAlgorithm _customFocusAlgorithm;
778 public CustomAlgorithmInterfaceWrapper()
782 public void SetFocusAlgorithm(FocusManager.ICustomFocusAlgorithm customFocusAlgorithm)
784 _customFocusAlgorithm = customFocusAlgorithm;
787 public override View GetNextFocusableView(View current, View proposed, View.FocusDirection direction)
789 return _customFocusAlgorithm.GetNextFocusableView(current, proposed, direction);