Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get percentage of scroll in NestedScrollView any time (smoothly)?

I want to change the alpha of toolbar base on scroll, like below:

enter image description here

At first, the toolbar is transparent and by scrolling to the bottom it will more and more visible and at the end it will be fully opaque (visible).

The structure of my layout is:

<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
    android:id="@+id/app_bar_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsing_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:contentScrim="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_collapseMode="parallax">

            ....

        </RelativeLayout>

    </android.support.design.widget.CollapsingToolbarLayout>

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
    android:id="@+id/scroll"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

         ....

    </android.support.v4.widget.NestedScrollView>

</android.support.design.widget.CoordinatorLayout>

Content of nested scrollview will be change dynamically from server so I don't know it's height.

I just found 2 ways to detect scrollY:

  1. addOnScrollChangedListener:

    scroll.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
     @Override
     public void onScrollChanged() {
        // use scroll.getScrollY()     
    }
    });
    
  2. setOnScrollChangeListener:

    scroller.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
    
    @Override
    public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
    
    }
    });
    

But none of these ways are not smooth. for example if you check the value of scrollY (by using log.d()) you will see something like:

scrollY: 58
scrollY: 117
scrollY: 167
scrollY: 192
scrollY: 195
scrollY: 238
scrollY: 281
scrollY: 338 

There is a large gap between numbers.

My question is: How to get percentage of scroll every moment (smoothly)? Or any other way to change alpha of toolbar base on current position of scroll?

like image 950
Hamed Ghadirian Avatar asked Oct 30 '16 21:10

Hamed Ghadirian


People also ask

What is nested scrolling ENABLED?

NestedScrollView is just like ScrollView, but it supports acting as both a nested scrolling parent and child on both new and old versions of Android. It is enabled by default. NestedScrollView is used when there is a need for a scrolling view inside another scrolling view.

How do I scroll to top programmatically?

scrollTo(0, 0); to scroll to the top of the NestedScrollView . You are welcome. This is more generally applied to both ScrollView or NestedScrollView.

How do I stop NestedScrollView scrolling?

setnestedscrollingenabled set it to false.

What is difference between nested ScrollView and NestedScrollView?

Nested scrolling is enabled by default. Show activity on this post. NestedScrollView is just like ScrollView, but in NestedScrollView we can put other scrolling views as child of it, e.g. RecyclerView. But if we put RecyclerView inside NestedScrollView, RecyclerView's smooth scrolling is disturbed.


3 Answers

Try this method:

    nestedScrollView.setOnScrollChangeListener((NestedScrollView.OnScrollChangeListener) (v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
                int verticalScrollableHeight = v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight();
                float verticalPercentage = ((float) scrollY) / verticalScrollableHeight;
like image 75
Maxim Firsoff Avatar answered Oct 17 '22 16:10

Maxim Firsoff


try this

scrollview.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
            @Override
            public void onScrollChanged() {
                double scrollViewHeight = scrollview.getChildAt(0).getBottom() - scrollview.getHeight();
                double getScrollY = scrollview.getScrollY();
                double scrollPosition = (getScrollY / scrollViewHeight) * 100d;
                Log.i("scrollview", "scroll Percent Y: " + (int) scrollPosition);
            }
        });

it will show the percentage from 0 to 100%

like image 34
Jimmy Cram Avatar answered Oct 17 '22 15:10

Jimmy Cram


You can add an scrollListener to ScrollView.

The calculation of scrolled percentage of your scrollView:

double percent = ((((float) scrollY) / ((float) (scrollContentHeight - screenHeight + statusBarHeight))));

enter image description here


  • The top edge of the displayed part of your view: scrollY = scrollView.getScrollY()

  • The scrollView has one child and scrollContentHeight = scrollView.getChildAt(0).getHeight() is the height of the content of scrollView.

  • We need to calculate the max height of top edge in full scrolled state: scrollContentHeight - screenHeight + statusBarHeight

  • Finished! percent = scrollY*100 / (scrollContentHeight - screenHeight + statusBarHeight)

  • And set the color: view.setBackgroundColor(Color.argb((int) (255.0 * (percent/100)), r, g, b));


scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
        @Override
        public void onScrollChanged() {
            int scrollY = scrollView.getScrollY();
            int scrollContentHeight = scrollView.getChildAt(0).getHeight();
            int screenHeight = Utility.getScreenHeight(context);
            int statusBarHeight = Utility.getStatusBarHeight(context);

            int color = getResources().getColor(R.color.colorPrimary);
            int r = (color >> 16) & 0xFF;
            int g = (color >> 8) & 0xFF;
            int b = (color >> 0) & 0xFF;

            double percent = ((((float) scrollY) / ((float) (scrollContentHeight - screenHeight + statusBarHeight))));
            if (percent >= 0 && percent <= 1)
                toolbar.setBackgroundColor(Color.argb((int) (255.0 * percent), r, g, b));
        }
    });
like image 31
Misagh Avatar answered Oct 17 '22 16:10

Misagh