Search code examples
androidgoogle-maps-android-api-2android-design-libraryandroiddesignsupportandroid-coordinatorlayout

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.


Solution

  • Update:

    I'm going to give you an overview how to do it (I can't post all the answer because I posted it in another question with MORE requeriments than question and my old answer got marked as duplicated...)any way this is how you do it:

    For custom CoordinatorLayout:
    Because you can't extend BottomSheetBehavior, you have 2 options: trying doing your own Behavior or like I did, just copy paste the code from original BottomSheetBehavior and modifying it to get another state (when google maps open a bottomsheet it stop in the middle of the screen, this is the state that I'm talking about).
    here the CustomBottomSheet with the behavior I was talking above

    Now for Image parallax effect:
    I tried all default parallax effect in XML avoiding a Custom behavior but in the end I ended doing one, its not hard, you need to override 2 methods like this:

    public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
        return dependency instanceof NestedScrollView;
    }
    
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child,
                                          View dependency) {
    
        if (mYmultiplier == 0) {
            initValues(child, dependency);
            return true;
        }
    
        float dVerticalScroll = dependency.getY() - mPreviousY;
        mPreviousY = dependency.getY();
    
        //going up
        if (dVerticalScroll <= 0 && child.getY() <= 0) {
            child.setY(0);
            return true;
        }
    
        //going down
        if (dVerticalScroll >= 0 && dependency.getY() <= mImageHeight)
            return false;
    
        child.setY( (int)(child.getY() + (dVerticalScroll * mYmultiplier) ) );
    
        return true;
    }
    


    Here the link to image parallax behavior

    And here is how its looks like:
    [CustomBottomSheetBehavior]

    A link to the project I must clarify that the previous link has FAB and toolbars animations but if you only want bottom and image behavior just ignore the others java files (clarifying because I have to "adjust to the question")