How to programatically scroll RecyclerView with a duration? - android

I have a horizontal RecyclerView and am attempting to programatically scroll by an x value.
This has so far been achieved with smoothScrollBy(x, y), however, I can't for the life of me find a solution where I can set a scroll duration, e.g. 1000ms.
Any help would me much appreciated, thanks.
The code is as follows:
private void focus() {
View focusedRecyclerViewItem = getFocusedRecyclerViewItem();
TextView focusedTextView = getFocusedTextView(focusedRecyclerViewItem);
focusedTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 64);
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
mRecyclerView.clearOnScrollListeners();
countdown();
}
});
int x = (int) focusedRecyclerViewItem.getX() - mRecyclerView.getWidth() / 2;
mRecyclerView.smoothScrollBy(x, 0);
}
To clarify as the question was not initially clear - what I am looking for is a custom duration for the smoothScrollBy() method when it is called, not a duration before the smoothScrollBy() method is called.

Related

How to find the item that shows up on top of the RecyclerView while scrolling [duplicate]

This question already has answers here:
Get visible items in RecyclerView
(11 answers)
Closed 3 years ago.
I have been looking for a proper API for what I need to do and I am all but certain that there has to be an API. But I am not finding it.
Here is my problem:
I am displaying an ArrayList inside a recycler view. What I need is to know what item in the ArrayList is showing at the top of the recycler view as I scroll up and down. Here is how I set up my recycler view (nothing special):
private ArrayList<Transaction> filteredTransactions = new ArrayList<>();
...
recyclerView = view.findViewById(R.id.feed_recycle_view);
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager((getActivity()));
adapter = new FeedAdapter(filteredTransactions);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(adapter);
I came across
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
that provides the listener I need, but I can't figure out how to get the item that appears on top of the view from it.
Thanks in advance
findFirstCompletelyVisibleItemPosition() will return the adapter position of the first fully visible view.
You can do it like this:
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int itemPoition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstCompletelyVisibleItemPosition();
// Get the item from the list
mList.get(itemPoition)
}
You can use the following methods of the LinearLayoutManager
int findFirstVisibleItemPosition();
int findFirstCompletelyVisibleItemPosition();
int findLastVisibleItemPosition();
int findLastCompletelyVisibleItemPosition();
Read the official document
There are some methods which are available in Linear Layout manager like
findFirstCompletelyVisibleItemPosition()
int findFirstVisibleItemPosition()
int findLastCompletelyVisibleItemPosition()
findLastVisibleItemPosition()
Go through the documentation it will surely help you.

How to know how many pixels were scrolled in RecyclerView?

I have a RecyclerView that contains different child views.
Then user scrolls it.
I want to know exactly how many pixels user scrolled in comparison with the beginning state.
In other words, I want to know exactly the distance (in pixels) from current content of screen and the first item of RecyclerView.
I see RecyclerView has a method computeVerticalScrollOffset. But that method returns wrong value.
It's possible with OnScrollListener. Override onScroll() method, and its arguments are the distance scrolled by horizontal or vertical axis.
But there are few problems. This passes not the final scroll value, but many values, u have to summarize until the state becomes RecyclerView.SCROLL_STATE_IDLE.
private class YourOnScrollListener extends RecyclerView.OnScrollListener {
private int scrollXDistance = 0;
private int scrollYDistance = 0;
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
Log.d(TAG, "X distance: " + scrollXDistance + " " + "Y distance:" + scrollYDistance);
}
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
scrollXDistance += dx;
scrollYDistance += dy;
}
}

Reycler view and custom parallax effect

I create parallax effect moving the image background depends on location of first element of recycler view only.
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if ((holder = recyclerView.findViewHolderForAdapterPosition(0)) != null) {
int offset = recyclerView.findViewHolderForAdapterPosition(0).itemView.getTop() / 10;
backgroundPhoto.setTop(offset);
}
The problem is : when the first item of recycler(header) scroll off the screen, background picture somehow jump ot initial position.
Once the view is scrolled off the screen the RecyclerView might still be able to access it but it's getTop() value will have some random value or 0 which will cause your parallax effect to jump.
You could keep a field in your class which saves the currently "scrolled distance" and add dx to it in the onScrolled(...) callback and use this value to calculate the parallax offset.

get scroll Y of RecyclerView or Webview

I have created a activity Webview content placed in Recyclerview.
I want to get the scroll Y position when I scroll webview.
I tried Webview.getScrollY(), Webview.getY(), RecyclerView.getScrollY(), RecyclerView.getY(),... but it do not work fine. I can't get current scroll Y.
Is there any suggest for get scroll Y of Webview or RecyclerView ?
Use a RecyclerView.OnScrollListener for the RecyclerView and a View.OnScrollChangeListener for the webview.
You'll have to keep track of the total scroll yourself, like this:
private int mTotalScrolled = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
mTotalScrolled += dy;
}
});
...
}
private int getScrollForRecycler(){
return mTotalScrolled;
}
computeVerticalScrollOffset()is more convenient at this situation as #Pkmmte mentioned.
mTotalScrolled = recyclerView.computeVerticalScrollOffset();

Expand Recyclerview item with animation when scrolling up

Iphone App video link
How I can design and develop view which is posted in above video? This is basically the item expansion of recyclerview with animation. I have tried with onItemtouchlistener of recyclerview and also with some custom view with animation, but didn't get the accurate result.
Finally i came accross addonscrolllistener, this give me results but not accurate.
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if(newState == RecyclerView.FOCUS_UP) {
System.out.println("hello, ia m going up");
}
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0){
TextView tv = (TextView)recyclerView.findViewById(R.id.title);
//tv.setVisibility(View.VISIBLE);
if (tv.getVisibility()==View.VISIBLE){
System.out.println("yes");
}else {
slideToTop(tv);
}
}
}
});
private void slideToTop(View view){
TranslateAnimation animate = new TranslateAnimation(0,0,0,-view.getHeight());
animate.setDuration(1000);
animate.setFillAfter(false);
view.startAnimation(animate);
view.setVisibility(View.VISIBLE);
}
I think your question is too broad - however, here is some psuedocode:
onScrolled() {
View child = getSecondVisibleChild();
int distanceFromTop = child.getTop();
int distanceAtWhichExpandingShouldOccur = 100;
if(distanceFromTop < distanceAtWhichExpandingShouldOccur ) {
child.setHeight(child.getOriginalHeight() + (distanceFromTop - distanceAtWhichExpandingShouldOccur))
}
}
So you'll notice, the second visible child is the one who's height changes. It changed when it's less than distanceAtWhichExpandingShouldOccur from the top of the window. Its height changes to ensure its bottom remains stationary - therefore its height is increasing at the same pace its top is moving.
Once it's no longer the second visible child (aka, its top is 0), it should be scrolled off as normal and the next child should have its height changed when its top is less than distanceAtWhichExpandingShouldOccur.
This library can be a study case for you: https://github.com/florent37/MaterialLeanBack

Categories

Resources