How to collapse/expand a view based on scroll direction?

前端 未结 4 1850
一整个雨季
一整个雨季 2020-12-11 04:39

I have a View and a RecyclerView housed in a LinearLayout. What I want to achieve is something like this:

https://material.google.com/patterns/scrolling-techniques.h

4条回答
  •  死守一世寂寞
    2020-12-11 04:46

    To achieve toolbar to expand and collapse smoothly you can apply translate animation or use CoordinatorLayout with AppBarLayout and Toolbar.

    Animation : First you have to detect scroll up and scroll down on your RecyclerView. To do so you can set “setOnScrollListener” on your RecyclerView. Once you have both scroll up and scroll down, simply apply animation.

    Code:

    rvHomeList.setOnScrollListener(new RecyclerView.OnScrollListener() {
    
                int verticalOffset;
    
                boolean scrollingUp;
    
                @Override
                public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                    if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                        if (scrollingUp) {
                            Log.e("onScrollStateChanged", "UP");
                            if (verticalOffset > llTop.getHeight()) {
                                toolbarAnimateHide();
                            }
                        } else {
                            Log.e("onScrollStateChanged", "down");
                            if (llTop.getTranslationY() < llTop.getHeight() * -0.6 && verticalOffset > llTop.getHeight()) {
                                toolbarAnimateHide();
                            } else {
                                toolbarAnimateShow(verticalOffset);
                            }
                        }
                    }
                }
    
                @Override
                public final void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    verticalOffset += dy;
                    scrollingUp = dy > 0;
                    int toolbarYOffset = (int) (dy - llTop.getTranslationY());
                    llTop.animate().cancel();
                    if (scrollingUp) {
                        Log.e("onScrolled", "UP");
                        if (toolbarYOffset < llTop.getHeight()) {
                            llTop.setTranslationY(-toolbarYOffset);
                        } else {
                            llTop.setTranslationY(-llTop.getHeight());
                        }
                    } else {
                        Log.e("onScrolled", "down");
                        if (toolbarYOffset < 0) {
                            llTop.setTranslationY(0);
                        } else {
                            llTop.setTranslationY(-toolbarYOffset);
                        }
                    }
                }
            });
    

    Animation Methods:

    private void toolbarAnimateShow(final int verticalOffset) {
            if (!isShowing) {
                isShowing = true;
                llTop.animate()
                        .translationY(0)
                        .setInterpolator(new LinearInterpolator())
                        .setDuration(180)
                        .setListener(new AnimatorListenerAdapter() {
                            @Override
                            public void onAnimationStart(Animator animation) {
                                llTop.setVisibility(View.VISIBLE);
                                isShowing = false;
                            }
                        });
            }
        }
    
        private void toolbarAnimateHide() {
            if (!isHidding) {
                isHidding = true;
                llTop.animate()
                        .translationY(-llTop.getHeight())
                        .setInterpolator(new LinearInterpolator())
                        .setDuration(180)
                        .setListener(new AnimatorListenerAdapter() {
                            @Override
                            public void onAnimationEnd(Animator animation) {
                                llTop.setVisibility(View.GONE);
                                isHidding = false;
                            }
                        });
            }
        }
    

    CoordinatorLayout with AppBarLayout and Toolbar: By using coordinatorLayout with appBarLayout and toolbar, and set the scroll flag used within the attribute app:layout_scrollFlags to achieve the scroll effect. It must be enabled for any scroll effects to take into effect. This flag must be enabled along with enterAlways, enterAlwaysCollapsed, exitUntilCollapsed, or snap.

    • enterAlways: The view will become visible when scrolling up. This flag is useful in cases when scrolling from the bottom of a list and wanting to expose the Toolbar as soon as scrolling up takes place.
    • enterAlwaysCollapsed: Normally, when only enterAlways is used, the Toolbar will continue to expand as you scroll down.Assuming enterAlways is declared and you have specified a minHeight, you can also specify enterAlwaysCollapsed. When this setting is used, your view will only appear at this minimum height. Only when scrolling reaches to the top will the view expand to its full height
    • exitUntilCollapsed: When the scroll flag is set, scrolling down will normally cause the entire content to move.By specifying a minHeight and exitUntilCollapsed, the minimum height of the Toolbar will be reached before the rest of the content begins to scroll and exit from the screen
    • snap: Using this option will determine what to do when a view only has been partially reduced. If scrolling ends and the view size has been reduced to less than 50% of its original, then this view to return to its original size. If the size is greater than 50% of its sized, it will disappear completely.

    Code:

    
    
        
    
            
    
                
    
                    
                
            
    
            
    
                
    
            
        
    
    
    

提交回复
热议问题