9

I'm trying to implement some kind of wheel picker for my app, because the current options rely on custom Views or the old ListView, so I'd like to base my solution on RecyclerView.

What I did until now was to set at the beginning and at the end of the RecyclerView two View with a different type, named PADDING_TYPE so that the first and the last item are vertically centered in the RecyclerView.

recyclerView.post(new Runnable() {
    @Override
    public void run() {
        //80dp is the height of a regular list item
        int paddingHeight = ((recyclerView.getHeight()-SettingsManager.dptopixels(80))/2);
        binding.getRoot().getLayoutParams().height = paddingHeight;
    }
});

Now I'm trying to understand how to keep the selected item vertically centered.

What I tried so far:

1- LinearSnapHelper

LinearSnapHelper helper = new LinearSnapHelper();
helper.attachToRecyclerView(mRecyclerView);

Does not work as expected, I also tried to Override several methods (probably in a wrong way), but I can't make it automatically vertically center the selection. And it's not snappy enough, the selected item "moves" instead of being locked to vertical center.

2- Custom RecyclerView.OnScrollListener

I tried to adapt the code proposed here, which is for horizontal scrolling, by changing in the RecyclerView.OnScrollListener this line

allPixelsDate += dx;

with the vertical scrolling difference:

allPixelsDate += dy;

This implementation is close to be working, because it selects the closest item to the vertical center of the list, but without locking it to the center.

Would it be possible to achieve such result? How?

To be more clear: I'd like to achieve the result shown here at 1:10. The selection is "locked" at center.

Community
  • 1
  • 1
Vektor88
  • 4,841
  • 11
  • 59
  • 111
  • try this code for reference [link](http://developer.samsung.com/s-pen-sdk/samples/Circle-Launcher) – Moinkhan Sep 01 '16 at 06:52
  • I have done this using https://github.com/ai212983/android-spinnerwheel and I think you need this in vertical Mannner https://github.com/Jaouan/Carousel-Browsing-Example – Zar E Ahmer Sep 06 '16 at 05:24
  • you can use this method in vertical to this achieve [open this ](http://stackoverflow.com/a/38411582/2587027) – wadali Sep 06 '16 at 10:19
  • @wadali it's exactly what I said I did, attempt number 2. Does not work. – Vektor88 Sep 06 '16 at 10:36
  • can you define `selected` item?? because in the video the selection is done using keys not touch! – Mohammad Ersan Sep 06 '16 at 15:27
  • @MoshErsan the selected item is the item at the center of the view. By either scrolling with a fling gesture or pressing a button you should get your rows content updated but no scrolling movement. – Vektor88 Sep 06 '16 at 15:50

1 Answers1

13

You just need to use LinearSnapHelper and the setOnFlingListener(snapHelper) method on your RecyclerView.

This is working example:

LinearSnapHelper snapHelper = new LinearSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setOnFlingListener(snapHelper);

To get real wheel picker you will also need to add some skin for your wheel and to accurately calculate height of rows and height of the RecyclerView. For example if you want to display only 3 rows in your wheel you need RecyclerView height to be 3 times larger than row height.

QED
  • 9,803
  • 7
  • 50
  • 87
lobzik
  • 10,974
  • 1
  • 27
  • 32
  • 1
    I tried the approach you suggested and it seems to behave the same as in my attempt number **1**. What I'm trying to achieve is the removal of any scrolling effect: The content of the rows should be updated by scrolling but rows should not move, in such a way that selection is "stuck" and vertically centered. With `LinearSnapHelper` it just regularly scrolls and tries - poorly - to snap the middle child to the center of its parent (the `RecyclerView`). To better understand what I mean, look https://www.youtube.com/watch?v=rercnPOELvs at 1:10 – Vektor88 Aug 28 '16 at 13:59
  • @Vektor88 How do you want user to change the selected item? By fling or not? – lobzik Aug 28 '16 at 14:13
  • Yes, have a look at the video. I want the fling to just cause update of rows and no scrolling movement. – Vektor88 Aug 28 '16 at 14:15
  • I suppose you should override LayoutManager and method canScrollVertically() to return false. Than override your fling listener (SnapHelper) to react on fling and change the item in center. – lobzik Aug 28 '16 at 14:25
  • When `canScrollVertically()` is set to `false` the `OnFlingListener` callbacks are not triggered. – Vektor88 Aug 28 '16 at 14:34
  • 1
    I don't know what the original guy was trying to achieve, but you saved my day, that is for sure. Thanks! – RexSplode Dec 16 '16 at 12:15
  • Do you need both `snapHelper.attachToRecyclerView(recyclerView)` and `recyclerView.setOnFlingListener(snapHelper)`? – QED Feb 01 '17 at 03:16
  • @lobzik any idea how to get listener when it auto adjust the middle item or middle item is being changed. – Muhammad Umar Feb 17 '17 at 14:35
  • this is what i was looking for...but one more thing first and last item never comes in centre.I want my list item should repeat like number picker do ,so that last and first item will also come in centre.any help please.thanks – Rishikesh pathak Apr 21 '17 at 06:32