Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make custom CoordinatorLayout.Behavior with parallax scrolling effect for google MapView?

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.

like image 931
LunaVulpo Avatar asked Nov 26 '15 18:11

LunaVulpo


1 Answers

As @Xaver Kapeller suggested, the most painless way to achieve the parallax is to wrap it in CollapsingToolbarLayout with collapsing mode PARALLAXand 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.

like image 112
Nikola Despotoski Avatar answered Nov 01 '22 11:11

Nikola Despotoski