I am learning Android CoordinatorLayout/RecyclerView/Behavior/Nested scroll stuff. I found the APIs are not very straight forward. Thus I did a little experiment but found the behaviors of views inside CoordinatorLayout do not come out as expected.
Here is what I want to do: I want to have a CoordinatoryLayout as the parent container. Inside it, there is a RecyclerView as its child. Also as its child, there is another View that is in red color. I want the red view to move as the RecyclerView scrolls. I want the movement of the two views so synchronized that it seems that the red view is part of the RecyclerView.
Note: I am aware that to achieve what I just said, there is much more simpler ways. But I just want to do it with CoordinatorLayout and Behavior class so that I can learn how they work.
Here is my layout file:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="io.github.seemuch.coordinatorlayoutexperiment.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="40dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:dividerHeight="10dp"
/>
<View
android:id="@+id/red_view"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginBottom="20dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="#ff0000"
app:layout_scrollFlags="scroll|enterAlways"
/>
</android.support.design.widget.CoordinatorLayout>
And here is my behavior class:
package io.github.seemuch.coordinatorlayoutexperiment;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.RecyclerView;
import android.view.View;
public class MyBehavior extends CoordinatorLayout.Behavior<View> {
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, View toolbar, View dependency) {
return dependency instanceof RecyclerView;
}
@Override
public boolean onStartNestedScroll (CoordinatorLayout coordinatorLayout,
View child,
View directTargetChild,
View target,
int nestedScrollAxes) {
int vertical = (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL);
int horizontal = (nestedScrollAxes & ViewCompat.SCROLL_AXIS_HORIZONTAL);
return (vertical != 0 && horizontal == 0);
}
@Override
public void onNestedPreScroll (CoordinatorLayout coordinatorLayout,
View child,
View target,
int dx,
int dy,
int[] consumed) {
float currY = child.getY();
if (currY <= 0 && dy >= 0) {
return;
}
child.setY(currY - dy);
}
}
As you can see in the onNestedPreScroll method, I want the child, which is the red_view, move as much as the view it depends on, which is the RecyclerView.
What actually happened was this: if you scroll the RecyclerView with very big movement, the red view does move with it, as expected; but if you move very little, the red_view moves much faster than the RecyclerView.
Here is a link to the screen record video: https://youtu.be/zK4g61F2aa0 And here is the Github repo of the project, incase you want to download it and run it yourself: https://github.com/seemuch/CoordinatorLayoutExperiment
So, anybody knows what happened? Thanks!