react-native-tvos icon indicating copy to clipboard operation
react-native-tvos copied to clipboard

Proposal : TVFocusGuideView for Android

Open prakashjais99 opened this issue 4 years ago • 8 comments

Currently, it's very difficult to direct Focus between Viewgroups of Touchables

ForExample

  1. In the below image it's very difficult to direct focus from any items in cluster 2 to the previously focused item in cluster 1 to achieve this currently we have to set nextFocusUp props for all the children in cluster 2 to cluster 1 last focused item id.
tv-nav-focusable-1
  1. In the below example from all the horizontal list items we should open a previously selected menu, which is the second item. For this, we have to set all the first items of lists nextFocusLeft to the 2nd menu item id
Screenshot 2021-08-06 at 4 19 12 PM

Also, one more problem is we have to pass node id between components to achieve this via props which make components reusability an issue

Solution If we have WrapperView like TVFocusFocusGuide which gets focus first for a cluster and then based on requirement we can pass the focus to any of its children's.

We have android:descendantFocusability and onRequestFocusInDescendants view group props which will let us achieve this behavior.

We can have a component that wraps touchable and controls the focus setup and movement between view groups.

prakashjais99 avatar Aug 06 '21 11:08 prakashjais99

This is a great idea, I wonder if we can extend TVFocusGuideView to have this behavior on Android.....

douglowder avatar Aug 06 '21 19:08 douglowder

@douglowder We can do like below

  1. Set the FocusGuideView to get the focus in the child View prior to it
setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
this.setFocusable(true);
  1. Record the focused view in the requestChildFocus method
@Override
public void requestChildFocus(View child, View focused) {
       super.requestChildFocus(child, focused);
    if (null != child) {
        mLastFocusViewID = child.getId()
    }
}
  1. When FocusGuideView is about to get focus, actively set the last focused View to get focus
@Override
public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
      View lastFocusedView = getLayoutManager().findViewById(mLastFocusViewID);
      if(lastFocusedView != null) {
             lastFocusedView.requestFocus();
             return false;
     }
}

We can have props to enable and disable this behavior and pass nodeId to override lastfocused id

prakashjais99 avatar Aug 07 '21 16:08 prakashjais99

API-wise, it would be great to have something like react-spatial-navigation.

TrebuhD avatar Oct 08 '21 12:10 TrebuhD

@TrebuhD that API looks VERY interesting indeed, thank you for letting me know.

douglowder avatar Oct 08 '21 17:10 douglowder

here's another interesting approach from ink, the React renderer for CLIs.

TrebuhD avatar Nov 22 '21 17:11 TrebuhD

@TrebuhD that API looks VERY interesting indeed, thank you for letting me know.

react-spatial-navigation

@douglowder Is this still being considered? I believe it still is a challenge to navigate through swimlanes

freemanchari avatar Jun 08 '22 04:06 freemanchari

@freemanchari I would consider adapting some of the APIs in https://github.com/NoriginMedia/Norigin-Spatial-Navigation, although they would necessarily work a little differently in RN.

As I don't have a lot of bandwidth at the moment, maybe @prakashjais99 or other Android developers could work on the TVFocusGuide implementation for Android TV first, and then we can see if the hook-based spatial navigation could be adapted for RN.

douglowder avatar Jun 08 '22 19:06 douglowder

Hello we needed this for our project so we worked the attached PR. It works afaics, as this is my first PR for this project, do not hesitate to let me know how I can improve it if needed.

SebastienChauvin avatar Jun 14 '22 08:06 SebastienChauvin

This feature is now merged and released, so closing this issue. :)

douglowder avatar Aug 24 '22 08:08 douglowder