Reycler view and custom parallax effect - android

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.

Related

How can I fetch dx that exist in RecyclerView directly?

I am currently experiencing an issue with scrolling my news ticker, similar to those found on news channels. To resolve this issue, I am using the following function to move the news ticker:
rv.smoothScrollBy(0, 0, new LinearInterpolator(), 10000);
-- The first parameter: I am currently unable to determine the correct value for this parameter.
-- The second parameter: As my RecyclerView orientation is horizontal (LinearLayoutManager), I am keeping it set to 0.
-- The third parameter: I do not require any additional effects, so I am using the LinearInterpolator.
-- The fourth parameter: I wish to move from the first scroll position to the last scroll position within the RecyclerView in 10 seconds, regardless of the text length.
Here is what I did to fetch dx
rv1.setAdapter(new CustomAdapter(MainActivity.this, strings));
rv1.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (!recyclerView.canScrollHorizontally(1))
Log.w("ABC", "dx is " + dx);
}
});
rv1.smoothScrollBy(100000000, 0);
Is there a way to determine the value for the first parameter without resorting to the workaround I have currently implemented? Specifically, can I fetch the value directly without having to move the scroll to the last position by adding a large number and then determine the dx value?

How to programatically scroll RecyclerView with a duration?

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.

Change firstCompletelyVisibleItemPosition() textcolor when recyclerview scrolling

I want to implement a recyclerview where the first visible items text color should change when scrolling. ie, the first visible item of recycler view have different color than other row items. I already tried several techniches but none of those worked. below is snap of my code
mListView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (!getUserVisibleHint()){
return;
}
int firstVisiblePosition=layoutManager.findFirstCompletelyVisibleItemPosition();
if (firstVisiblePosition==mLastReadPosition)return;
if(firstVisiblePosition!=-1){
View view =layoutManager.findViewByPosition(firstVisiblePosition);
listAdapter.setViewRead(view,firstVisiblePosition);
if (mLastReadView!=null){
listAdapter.setViewUnRead(mLastReadView);
}
mLastReadView=view;
mLastReadPosition=firstVisiblePosition;
}
}
this work when I scroll reversely,but not working on forward scrolling. I already searched for libraries in GitHub, If you know any libraries please suggest. Or help me for resolve this>?

How do I move views with RecyclerView.OnScrollListener, while keeping rotation sanity?

I have a layout with a RecyclerView (simple vertical list). When the list is scrolled up, some views (including the recyclerview) move with it and stick to the top of the screen. Scrolling down, they move down until they return to their initial position. Their translationY are tied to how much the list has been scrolled up or down.
Problem is, I have a static layout for landscape, so rotation does all sorts of weird things to the layout. How do I prevent this? In other words, how do I keep the views within setTranslationY bounds?
The layout:
<LinearLayout
android:id="#+id/rootLayout"
...
>
<Some other stuff/>
<RelativeLayout
android:id="#+id/containerLayout"
>
... contains things ...
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
/>
</LinearLayout>
And the code:
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
scrollY = scrollY - dy // float, to keep the total vertical scroll amount
final int maxTop = rootLayout.getTop() // Maximum translationY allowed, sticky to top
containerLayout.setTranslationY(maxTop > scrollY ? maxTop : scrollY) // if it reached the top, stay there
recyclerView.setTranslationY(maxTop > scrollY ? maxTop : scrollY) // the same
}
This works well enough. The problem is when I rotate the device, the layouts move into wacky positions or entirely off-screen because of the recycler view behaviour.
Any help would be appreciated, I'm losing my sanity here.

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