Android TV RecyclerView focus interaction - android

I'm currently using a regular RecyclerView with GridLayoutManagerwith different spanCount depeding on the viewType for an Android TV app. All is working decent but I have 2 issues:
If you long press the dpad down to scroll fast between the items sometimes the focus is lost to a view that isn't a child of the RecyclerView.
How can I tell the RecyclerView to keep the current focused view in the center of the grid?
It seems that the issues listed are fixed by using the VerticalGridView from LeanBack library but the LayoutManger that it uses is internal and doesn't support spanCount.

For a regular RecyclerView,
I had to specify: android:descendantFocusability="beforeDescendants"
And also android:nextFocusDown="#+id/recyclerviewId" is set to send focus to RV itself.
The only solution I see is a key listener to select item to position currentPosition + spancount.

Recycler view works fine with android TV.Possible solutions you can include are:
1.add focusable and focusableInTouchode to view.Add focusListner through the code and request focus each time when the view is clicked.
2.To keep Recycler View focused item in the centre you have to override layout manager just like this example.
RecyclerView smoothScroll to position in the center. android
or
use layoutManager.scrollToPositionWithOffset(position,offset) where position-focused view position and offset is the recycler view width/2.

You can try to check this workaround for the bug with RecycleView focus scrolling when navigating with d-pad.
Here is the SO question for that.
The problem here is that the GridLayoutManager uses LinearLayoutManager's implementation of onFocusSearchFailed() which is called when focus approaches the inner border of RecyclerView. LinearLayoutManager's implementation just offers first/last (depends on scrolling direction) element. Hence focus jumps to first/last element of new row.
So, maybe this workaround will solve your issue or give you an idea on how to solve your problem.

Related

Recyclerview grid layout: Drag outside incompatible with scrolling?

I am building an android app with two recyclerviews, one with horizontal LinearLayoutManager and the other one with GridLayoutManager.
I want to allow the items recyclerviews to be dragged and dropped over a trash icon outside of the recyclerviews, obviously to delete the dragged item.
What I have done is:
Apply android:clipChildren in the parent of the two recyclerviews
Apply android:clipToPadding in the recyclerviews
This works perfectly in recyclerview with LinearLayoutManager. I can drag an item and drop it over an icon that is outside of the recylcerview.
I also works in the recyclerview with GridLayoutManager, but with a side effect. When I scroll in the grid recyclerview the scrolled items come out of the recyclerview.
At the ende of this GIF you can see the scrolling issue
So, Is there any way to allow dragging a recyclerview item outside of the recyclerview boundaries but preventing items comeout when scrolling?
Lots of thanks for your help and suggestions in advance
I tried putting the recyclerview with LinearLayoutManager on top of the recyclerview with GridLayoutManager, to hide the items which came out of the boundaries, but this make a strange behaivour when I drag an item, because the items are there yet, even they are hidden. I could make a GIF if needed
My last option is putting the trash icon inside of the recyclerview, as a header that appears when dragging an item, but I would prefer not do it that way
Finally what I have learnt is that you have two main options when face a drag and drop problem:
Easy way: Using the Android helper ItemTouchHelper
Hard way: Not using the helper and type all the code, using startDragAndDrop()
A scenario like this only can be solved by the hard way.

Focus switching to next row in nested recyclerview in FireTv App

In our fire tv app, we are using a nested recyclerview where every vertical item have a horizontal row as a child item like playstore design.
Scrolling with dpad working fine normally but when i hold the right key for few seconds, item start scrolling very fast because it gets many events & within few second focus goes to the next random row even current row has items to scroll. So this whole problem happening in horizontal scroll(child recyclerview). I have already tried many solutions like this, this, this.
Also tried the custom layout manager, custom focus layout & other approach like slowing down the recyclerview scroll etc approach but all not working.
As far as I know, this happens at the moment when the last item is in focus, and the next item is not visible, that is, the ViewHolder has not updated the data of the first cell, so it is not clear which element to show next as if the list has ended.
You need to make sure that at least the edge of the next element is always visible on the screen.
Maybe you should play with the cell size or divider.
Edit:
The secret is to use the leanback library. It isn't lost focus!
Your gradle:
// Leanback support
def leanback_version = "1.2.0-alpha01"
implementation("androidx.leanback:leanback:$leanback_version")
Change in the layout from RecyclerView to HorizontalGridView (VerticalGridView)
Change in the Fragment import from RecyclerView.widget.GridLayoutManager to androidx.leanback.widget.GridLayoutManager
It works very fast for me and the focus no longer jumps.
Here a good article with animations but little outdated

How to make row list using recyclerView and card? Can I use Nested RecyclerView?

I'm trying to design a row list using RecyclerView like Android TV ↳ android.support.v17.leanback.widget.ListRow. I'm able to design list with title but not row list. Can anyone help me?
Please Follow this Link for
Recycer view like play store
Use Two RecyclerView Outer Recycler is vertical and Second horizontal recycler is item of first recycler View
All you need is to call mInnerRecycler.setNestedScrollingEnabled(false); on your inner RecyclerViews and use Horizontal scrollview as root of mInnerRecyclerView
Explanation:
RecyclerView has support for nested scrolling introduced in API 21 through implementing the NestedScrollingChild interface. This is a valuable feature when you have a scrolling view inside another one that scrolls in the same direction and you want to scroll the inner View only when focused.
In any case, RecyclerView by default calls RecyclerView.setNestedScrollingEnabled(true); on itself when initializing. Now, back to the problem, since both of your RecyclerViews are within the same ViewPager that has the AppBarBehavior, the CoordinateLayout has to decide which scroll to respond to when you scroll from your inner RecyclerView; when your inner RecyclerView's nested scrolling is enabled, it gets the scrolling focus and the CoordinateLayout will choose to respond to its scrolling over the outer RecyclerView's scrolling. The thing is that, since your inner RecyclerViews don't scroll vertically, there is no vertical scroll change (from the CoordinateLayout's point of view), and if there is no change, the AppBarLayout doesn't change either.
In your case, because your inner RecyclerViews are scrolling in a different direction, you can disable it, thus causing the CoordinateLayout to disregard its scrolling and respond to the outer RecyclerView's scrolling.
Notice:
The xml attribute android:nestedScrollingEnabled="boolean" is not intended for use with the RecyclerView, and an attempt to use android:nestedScrollingEnabled="false" will result in a java.lang.NullPointerException so, at least for now, you will have to do it in code.
RecyclerView can check View Type for return header or item. And use layout manager for manage how to item scrolling direction.
RecyclerView (vertical scrolling)
- item -> RecyclerView (horizontal scrolling) check view type is header or item with condition example : is object has type header
Ref : Google play store like interface using recycler view

Why RecyclerView items disappear immediately when using Transition API?

This is a question regarding the use of Android Transition API.
I am trying to animate the height change of a list, just like a dropdown menu.
I tried 2 approaches
Use a RecyclerView and animates its height change
Use a ScrollView > LinearLayout hierarchy and animates ScrollView's height.
The 2nd approach works perfectly.
But the 1st approach has a serious glitch - when the collapse transition starts, items disappear immediately.
By looking at the below GIF you can observe clearly the difference:
To be exact, items' visibility changes at the moment I change RecyclerView's LayoutParams, without waiting for the transition to finish, whatever it is expanding or collapsing
Code
I have created a minimal project on Github.
If you just want to look at the code, here is the MainActivity.
Question
Is it possible to achieve ScrollView's effect with a RecyclerView?
If yes, how?
My Idea is to do the transition of all the recycler view rows individual rather than the whole RecyclerView:
So when collapsing iterate through each ROW of a RecyclerView and do a transition. Remember to check for null if some rows are recycled they may return null. So after that collapse the whole recyclerView.
And like wise for the expanding do the same for the views.
This issue is cause by RecyclerView has many views with it but Scroll View has only one View nested in it.

Have an item stick to the bottom of a RecyclerView

I have a vertically scrollable list using a RecyclerView. The layout I'm trying to implement is that when you scroll down far enough and reach a specific item, if you keep scrolling past this item it will stick to the bottom of the screen while the rest of the list continues to scroll behind it. Currently it's implemented by having a scroll listener on the RecyclerView and manually adjusting the position of the sticky view as required, but this is hacky and hard to build on.
Is there an easier way to have this kind of layout? I am currently investigating using a CoordinatorLayout but I'm not sure if it's the right tool for the job.
You can accomplish this using a CoordinatorLayout with a custom behaviour. The behaviour should be applied to the sticky view and make it appear/disappear as the RecyclerView scrolls. You have to override onStartNestedScroll in your behaviour to return true to receive calls for scroll changes.

Categories

Resources