How to expand AppBarLayout when scrolling down reaches at top of the RecyclerView

前端 未结 1 596
终归单人心
终归单人心 2020-12-29 06:34

I am working on one android app in which I am using CoordinatorLayout,AppBarLayout and CollapsingToolbarLayout to use the advance coll

相关标签:
1条回答
  • 2020-12-29 06:59

    I've just put together a sample app that seems to demonstrate the behaviour you're after. The AppBar will automatically expand whenever the RecyclerView beneath it is scrolled to the top, rather than stopping and waiting for another swipe to open the AppBar.

    The most relevant components reside in a custom RecyclerView class. I've added a few explanatory comments:

    public class ScrollFeedbackRecyclerView extends RecyclerView {
    
        private WeakReference<Callbacks> mCallbacks;
    
        public ScrollFeedbackRecyclerView(Context context) {
            super(context);
            attachCallbacks(context);
        }
    
        public ScrollFeedbackRecyclerView(Context context, AttributeSet attrs) {
            super(context, attrs);
            attachCallbacks(context);
        }
    
        /*If the first completely visible item in the RecyclerView is at
        index 0, then we're at the top of the list, so we want the AppBar to expand 
        **if the AppBar is also collapsed** (otherwise the AppBar will constantly 
        attempt to expand).
        */
        @Override
        public void onScrolled(int dx, int dy) {
            if(((LinearLayoutManager)getLayoutManager()).findFirstCompletelyVisibleItemPosition() == 0) {
                Log.e(getClass().getSimpleName(), "index 0 visible");
                if(mCallbacks.get().isAppBarCollapsed()) {
                    mCallbacks.get().setExpanded(true);
                }
            }
            super.onScrolled(dx, dy);
        }
    
        /* the findFirstCompletelyVisibleItem() method is only available with 
        LinearLayoutManager and its subclasses, so test for it when setting the 
        LayoutManager
        */
        @Override
        public void setLayoutManager(LayoutManager layout) {
            if(!(layout instanceof LinearLayoutManager)) {
                throw new IllegalArgumentException(layout.toString() + " must be of type LinearLayoutManager");
            }
            super.setLayoutManager(layout);
        }
    
        private void attachCallbacks(Context context) {
    
            try {
                mCallbacks = new WeakReference<>((Callbacks)context);
            } catch (ClassCastException e) {
                throw new ClassCastException(context.toString() + " must implement " +
                        "ScrollFeedbackRecyclerView.Callbacks");
            }
    
        }
    
        /* Necessary to interact with the AppBarLayout in the hosting Activity
        */
        interface Callbacks {
    
            boolean isAppBarCollapsed();
            void setExpanded(boolean expanded);
    
        }
    }
    

    MainActivity.java

    public class MainActivity extends AppCompatActivity implements ScrollFeedbackRecyclerView.Callbacks{
    
        private AppBarLayout mAppBarLayout;
        private Toolbar mToolbar;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            ScrollFeedbackRecyclerView mRecyclerView = (ScrollFeedbackRecyclerView) findViewById(R.id.rv_container);
            RecyclerViewAdapter mAdapter = new RecyclerViewAdapter();
    
            mRecyclerView.setAdapter(mAdapter);
            mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    
            mAppBarLayout = (AppBarLayout) findViewById(R.id.app_bar);
            mToolbar = (Toolbar) findViewById(R.id.toolbar);
    
        }
    
        /* When collapsed, calling getY() on the AppBar will return a negative number. 
        Adding this number to getHeight() will return the same value as the toolbar's 
        height if the AppBar is fully collapsed.
        */
        @Override
        public boolean isAppBarCollapsed() {
            final int appBarVisibleHeight = (int) (mAppBarLayout.getY() + mAppBarLayout.getHeight());
            final int toolbarHeight = mToolbar.getHeight();
            return (appBarVisibleHeight == toolbarHeight);
        }
    
        @Override
        public void setExpanded(boolean expanded) {
            mAppBarLayout.setExpanded(expanded, true);
        }
    }
    
    0 讨论(0)
提交回复
热议问题