0

I want to implement this

this.

I want to check if the clicked item is fully visible and if it's not I would like to smoothly scroll upwards/downwards. I have a GridLayoutManager with 3 columns. The items are all of the same size, and are just ImageViews.

I am able to get the RecyclerView to scroll with:

@Override
    public void onClick(View view) {
        int adapterPosition = RecHolder.this.getAdapterPosition();
        mRecyclerView.scrollToPosition(adapterPosition);
        ...
}

But it's not a "scroll", it's very laggish and way too quick. If I try to use mRecyclerView.smoothScrollToPosition(adapterPosition); the result is the same. Exactly the same movement, there is no visible difference.

David
  • 11
  • 3

1 Answers1

-1

Don't bother testing to see if it's not completely visible. Just insert a command to scroll to that position. Since you didn't post any of your code I can't specifically say how you would do it. I personally have my adapter create an intent and my activity handles the intent. If that's what you're doing then you can include the getAdapterPosition() as an extra like this (vh is my ViewHolder).

vh.mImageView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        SelectItemGridAdapter.ContentViewHolder vh = (SelectItemGridAdapter.ContentViewHolder) (((View)v.getParent()).getTag());
        Intent intent = new Intent(ACTION_SELECT_Item);
        intent.putExtra(Constants.MSG_TYPE, SELECT_ITEM_TAPPED);
        intent.putExtra(SELECT_ITEM_TAPPED_ID, vh.viewModel.mItemId);
        intent.putExtra(SELECT_ITEM_TAPPED_POS, vh.getAdapterPosition());
        LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
    }
});

Then the reveiver in the activity can get the SELECT_ITEM_TAPPED_POS value...

int pos = intent.getIntExtra(SelectItemGridAdapter.SELECT_ITEM_TAPPED_POS, -1);
if (pos > -1)
    rv.scrollToPosition(pos);

HTH, Mike

Mike
  • 788
  • 10
  • 27
  • I'll be really happy to hear a better one. – Mike Sep 08 '17 at 22:42
  • You obviously know what the Observer pattern is, and what a Callback is? `OnClickListener()` is an example - so I'll assume yes. However you are using a comparatively expensive LocalBroadcast/Intent sending parcelled primitives to the HOSTING `Activity` - how does this make any sense? Use a callback, thats all is needed, whether thats an implemented interface by the `Activity` or using a library like RxJava, something like : https://stackoverflow.com/a/30285361/4252352 . Also this seems just like a copy paste of some code you've used, not tailored as an answer to the question. – Mark Sep 08 '17 at 22:52
  • I'm a bit new to Android an this is from my first project. The intent (pardon the pun) was to make the view re-usable and de-coupled from the activity. So all it's supposed to do is announce to its owner that something was tapped / long tapped and let the activity decide what to do. A callback is an interesting idea there tho. I'll check that out. Your sample didn't include one but I'll see if I can find one that does. As for it being not tailored to the question, it's a solution that scrolls the item into position when it's tapped. The OP gave no hint about his implementation. – Mike Sep 09 '17 at 00:09
  • Well an interface is decoupled, its just a contract that any class can implement. This sort of pattern is common place in any event driven OS/Framework. I recommend that you start looking a RxJava, which is all about Observers and Observables, it is built upon the Observer pattern idea and is a popular library (I believe it has 9+ language implementations now), also its independent of Android, meaning its just pure Java. Also as to the OP's question, it should be closed as its poor quality and is way off this - https://stackoverflow.com/help/mcve – Mark Sep 09 '17 at 09:19
  • So I was able to get the RecyclerView to scroll to the clicked item, that's fine, but I can't implement smooth-scrolling so it doesn't actually look like it's scrolling but it just "teleports" the item into view and it's very laggish. @MarkKeen what's wrong with the answer? it's pretty straightforward – David Sep 09 '17 at 14:24
  • @David - what you have done isn't a implementation of the answer (you've simply got a click listener, no intent/broadcast or receiver etc), so its not really a valid question to me.. – Mark Sep 09 '17 at 15:21
  • Yes and I never intended to use a listener. I really think that .scrollToPosition() should accept a int parameter for example to assign the scroll duration or something. Why is this so difficult? – David Sep 09 '17 at 15:26
  • @David - Sorry I should have used smoothScrollToPosition. You have to have a layoutManager set and for some it appears they needed to customize it somewhat. If you search on that function I'm sure you'll find what your looking for. – Mike Sep 09 '17 at 18:18
  • @MarkKeen an UI isn't decoupled if you decide what to do with the item from within the UI. In the post that you referenced you used Toast in the vh when it was tapped. Meaning the only thing that UI is good for is making toast. Possibly that was just a sample and not really fleshed out to serve the purpose of the OP's request. That wouldn't explain why you would come down on me for providing a solution not tailored to the question. – Mike Sep 09 '17 at 18:29
  • Well this is kind of a pointless argument, I have explained why your idea isn't good, take it or leave it? I have updated the previous link to the example. Your answer isn't tailored - you reference variables that don't exist in your code i.e. you gave concrete code, but really just an idea. – Mark Sep 09 '17 at 19:36
  • @Mikey I am using a GridLayoutManager which I can't find any way to modify. I found a good solution but it only works for the Linear one. https://mcochin.wordpress.com/2015/05/13/android-customizing-smoothscroller-for-the-recyclerview/ – David Sep 10 '17 at 20:34