I need a component that works like the picture below but I'm having trouble coming up with some kind of decent solution that works.
I want the list to have a center locked selection but being scrollable with the d-pad. This is for an application running on a TV so no need for touch scroll. So when pressing down on the remote d-pad the list will scroll and a new item will size up and the current selected one will size down and the new selection will still be in the middle.
I've tried doing this using a ListView that I extended and programmatically scrolling when pressing down or up. On scroll finished I called notifyDatasetChanged() on the ListView for re-inflating of the childs and in the ListViews adapters getView() I made the animation of the view located at the current selected position.
This is not optimal since I need to call notifyDatasetChanged(), which re-inflates all visible views, for the animation to apply. The UI becomes laggy when doing this and scrolling fast. It's also not possible to make som kind of compress animation when current selected item goes out of selection. There is also some trouble with the end items (read views) such the first or last in the list when doing animation of them, the may sometimes go out of screen.
I think that his must have been done before and maybe I'm missing it when searching for an answer.
Have anyone done something similar or do you have some suggestions of how this can be achieved? Maybe I'm just starting of with the wrong component here..
Regards,
Kristoffer
Related
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
I want to animate the RecyclerView scrolling. I don't want to animate adding or removal of items but rather animate items which are on screen, i.e visible items. What I want is, item settle down smoothly when scrolling is about to finish. I am not sure what approach should I take or how this can be done. I have tried following till now
Using RecyclerView.OnScrollListener, when I get onScrolled callback, I find visible items & animate them upside or downside based on scroll direction. But this approach is no-where near to perfect & many times when scrolling fast, some visible views are null so animation doesn't apply on them & it looks weird.
Tried to animate visible items when I receive SCROLL_STATE_IDLE. But there's noticeable delay for a fraction of second when scrolling is finished & then items animate. It doesn't look natural
Tried to figure out when RecyclerView scrolling is "about to" finish so I can start animation to mimic continuity of animation with scrolling. But didn't get success in identifying reliably that scrolling is about to finish.
Instead of above a little complex ways that doen't work the way I need, I wonder if there is any other way like creating custom LayoutManagerwhere I can override the each item scrolling so that it settle to it's aimed position smoothly?
Edit: Here's something very close to what I wanted
I need to do some animations in a listview after it is flinged and is about to stop.I have a listview which is going to be of a fixed height(well dont ask me why), and whenever the scroll stops , it should have three elements visible. What i do now is detect when the list reaches SCROLL_STATE_IDLE and if i have two elements visible at that time, i use smoothScrollToPosition and reach a state of 3 items visible and it works fine, but what i would like to do is detect when the scroll is about to stop and stop the scroll programatically when there are three items visible. Is that even possible... Any code snippets, pseudo code, algo would help me.
You can set an OnScrollListener, and then store the value from absListView.getScrollY() each sample and compare it the previous sample to compute the velocity of the scroll. Once that drops below a threshold you define, you can take over scrolling.
I have a button in each item of a ListView whose background is defined by an XML, one background when enabled and another when disabled. When the ListView loads, it comes out correct. But, for some reason I can't figure out, if I scroll down and then scroll back up, the wrong background shows up.
I'd like to know the solution to this problem, but besides that, in general what I want to accomplish is this:
I have a button in the ListView to take the user to the website for the given item. If there is no website, I want the button to disappear, or be disabled. I seem to have the same problem with both options.
Thanks in advance for your efforts
It seems most likely that the problem lies with your getView() method. Android recycles views to save memory, so, for example, when you scroll down, it calls getView(int, View, ViewGroup) on your adapter where View is the item that just left the top of the screen. If you're not re-populating the item with the new data from the adapter, (ie, just returning convertView) it will put the View that left the top of the screen where the "new" one should be.
I have a ListView in my Android application. The individual views in the list are a little bit smaller than the size of the screen.
I want the list to always show one item centered in the screen, with just a small sliver of the previous and next items showing above and below it.
When the user scrolls, I need to reposition the child view at position 0 or 1 (depending on which way they are scrolling). Currently I am doing this by calling "setSelectionFromTop" in my onScrollStateChanged method. This works, but the transition is immediate, not smooth. It is jarring and confusing in a lot of cases.
What's the best approach to fixing this? I want to animate the process of scrolling the list into the position I want, but I can't find any methods in ListView or its superclasses that let me directly control the scroll position of the entire list.
I think I could animate it using multiple calls to setSelectionFromTop(int position, int y) with progressive values of y, but I don't know how to determine the initial value of y. Is there some way to get that by interrogating the view object at the designated position?
Another challenge I have in front of me is that I want to animate the removal of an item from the list - by having it either disappear or slide away to the left, and then having the surrounding views move up and down to fill the space. Is there a straightforward and reliable way to do this with a ListView? Should I just give up on the ListView and write the whole thing as a custom view from scratch?
Thanks.
This definitely should be possible. Does smoothScrollToPosition() work?
Otherwise, you can try simulating the touches using TouchUtils.