Renan Nery
Renan Nery

Reputation: 3755

Show shadow elevation on bottom view when a ScrollView or RecyclerView Z index is smaller - Android Material Design

I used to force a shadow below my toolbar view for a better backwards support like this:

<View
            android:id="@+id/toolbar_shadow"
            android:layout_width="match_parent"
            android:layout_height="4dp"
            android:layout_below="@+id/toolbar"
            android:background="@drawable/shadow_elevation" />

@drawable/shadow_elevation

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient
        android:angle="90"
        android:endColor="#12000000"
        android:startColor="@android:color/transparent" />
</shape>

enter image description here

Now I need to do the same effect, but in the bottom something like this

<--Toolbar-->
<--toolbar shadow-->
<--Scroll View-->
<--bottom shadow-->
<--Bottom Layout-->

The problem is, I don't want to keep the bottom shadow always visible, I want to show the 'bottom shadow' only when the scrollview is 'below' the bottom layout, talking about Z indexes.

In other words what I need is to show bottom shadow when scrollview bottom hit the bottom layout top.

This is the layout without shadow on bottom view:

enter image description here

I've been thinking to do this on the code, checking Y index of view and if they are they same, that's mean that the bottom layout need to have a higher elevation/translationZ than Scrollview, but I'm not sure if this is the best option, I think that maybe there is a way just setting my layout properly.

Any ideas?

Upvotes: 3

Views: 2562

Answers (1)

Renan Nery
Renan Nery

Reputation: 3755

I found a way! I completely forgot to put it here

For those in need, it's been working nice so far.

public void setBottomLayoutElevation(View scrollView, View bottomView) {

    if (scrollView instanceof NestedScrollView) {
        NestedScrollView nestedScrollView = (NestedScrollView) scrollView;
        nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
            @Override
            public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {

                int max = nestedScrollView.getChildAt(0).getHeight() - nestedScrollView.getHeight();

                if (v.canScrollVertically(1)) {
                    int abs = Math.abs((scrollY * 100 / max) - 100);
                    ViewCompat.setElevation(bottomView, Math.min(abs, 40));
                } else {
                    ViewCompat.setElevation(bottomView, 0);
                }
            }
        });
    }

    if (scrollView instanceof RecyclerView) {
        ((RecyclerView) scrollView).addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                ViewCompat.setElevation(bottomView, recyclerView.canScrollVertically(1) ? 30 : 0);
            }
        });
    }
}

Upvotes: 3

Related Questions