I try to make a parallax scrolling effect for google MapView
and RecycleView
using CoordinatorLayour
.
so base on some tutorials found on web I made below code.
The layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.gms.maps.MapView android:id="@+id/map_view"
android:layout_width="match_parent"
android:layout_height="200dp"
app:layout_behavior="net.lunavulpo.coordinatorlayouttest.MapViewBehavior"
/>
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_marginTop="200dp"
android:layout_height="match_parent"/>
</android.support.design.widget.CoordinatorLayout>
and I made my implementation of CoordinatorLayout.Behavior
:
public class MapViewBehavior extends CoordinatorLayout.Behavior<MapView> {
public MapViewBehavior(Context context, AttributeSet attrs) {
}
@Override
public boolean layoutDependsOn(CoordinatorLayout parent, MapView child, View dependency) {
return true;
}
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, MapView child, View directTargetChild, View target, int nestedScrollAxes) {
return true;
}
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, MapView child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
//child.setTranslationY(child.getTranslationY() - dyConsumed);
child.setBottom(child.getBottom() - dyConsumed);
//what should I make here?
}
@Override
public boolean onNestedFling(CoordinatorLayout coordinatorLayout, MapView child, View target, float velocityX, float velocityY, boolean consumed) {
//what should be here?
return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed);
}
@Override
public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, MapView child, View target, float velocityX, float velocityY) {
//what should be here?
return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);
}
}
How to correct implement the parallax scrolling effect? Maybe there is a library with ready to use Behaviors? or I miss something and there is a simplest way?
I don't want to use Toolbar for this at all.
As @Xaver Kapeller suggested, the most painless way to achieve the parallax is to wrap it in CollapsingToolbarLayout
with collapsing mode PARALLAX
and parallax multiplier of your choice.
However, if you plan to go with your own behavior, you need to write the implementation in the onPreNestedScroll()
method.
First, you only care about vertical scrolling. In onStartNestedScrolling()
you check wither nestedScrollAxes
is vertical.
Then you accumulate all the dy
scrolled and translate the dummy view (that works as header) and MapView
. Reset the mTotalDy
to 0
when there is a change in the direction of scrolling.
Then for the same negative mTotalDy
value translate the ViewCompat.setTranslationY(mDummyView, -mTotalDy)
. To achieve proper parallax, the parallax should translate slower than the dummy view, which means that the mTotalDy
value should be at least half the speed of translation speed of the dummy view, i.e: ViewCompat.setTranslationY(mMapView, -mTotalDy/2)
. Therefore you will see it translating up/down slower.
View hierarchy should be: Make sure your z-order is preserved as I described
-CordinatorLayout
-FrameLayout
-MapView
-DummyView (same height as MapView, different z-order)
-NestedScrollView (same z-order as DummyView)
You should handle in the same manner when there is nested flinging, hint: use target.getScrollY()
, where the target is the view that scrolls.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With