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

£可爱£侵袭症+ 提交于 2019-11-29 02:16:43

问题


I am working on one android app in which I am using CoordinatorLayout,AppBarLayout and CollapsingToolbarLayout to use the advance collapse bar functionality.

I am using recyclerview to show the number of items in the fragment. When I'm scrolling up recyclerview it smoothly collapse AppBarLayout but when I scroll down and reach at on the first item of the recyclerview it automatically stop scrolling without expanding `AppBarLayout'.

Then again I need to scroll down again to make AppBarLayout visible. So my requirement is that on scrolling down when I reach to top of recyclerview it must expand `AppBarLayout'.

How can we do this. Any idea ? Please see video of same https://www.dropbox.com/s/va5jk27ikytk5ax/app_collapsebar_issue.mp4?dl=0

Here is my layout of same :-

<?xml version="1.0" encoding="utf-8"?>

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawerLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"

    android:fitsSystemWindows="true">

    <FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <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:id="@+id/coordinator"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:adjustViewBounds="true"
        android:fitsSystemWindows="true"
        app:layout_scrollFlags="scroll|exitUntilCollapsed"
        >

        <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="220dp"
        android:background="@drawable/offer_image"
        android:fitsSystemWindows="true"
        android:theme="@style/AppTheme.AppBarOverlay"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

        <!--    <com.flaviofaria.kenburnsview.KenBurnsView
            android:id="@+id/image"
            android:layout_width="match_parent"
            android:layout_height="220dp"
            android:src="@drawable/offer_image" />-->
        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            app:expandedTitleMarginEnd="64dp"
            app:expandedTitleMarginStart="48dp"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">


            <com.flaviofaria.kenburnsview.KenBurnsView
            android:id="@+id/image"
            android:layout_width="match_parent"
            android:layout_height="220dp"

            android:src="@drawable/offer_image" />

            <FrameLayout
            android:id="@+id/collapse_frame"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#B3c85a00">

            </FrameLayout>

            <FrameLayout
            android:id="@+id/centerCircle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center">

            <ImageView
                android:id="@+id/imageViewCenter"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:src="@drawable/offer" />
            </FrameLayout>

            <include
            android:id="@+id/toolbar"
            layout="@layout/toolbar" />

            <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:layout_marginBottom="15dp"
            app:tabIndicatorColor="#FFFFFF"
            app:tabMode="scrollable" />
            <!--</FrameLayout>-->
        </android.support.design.widget.CollapsingToolbarLayout>
        </android.support.design.widget.AppBarLayout>

        <!--<FrameLayout-->

        <!--android:layout_width="match_parent"-->
        <!--android:layout_height="match_parent"-->
        <!-- -->
        <!--android:visibility="visible">-->

        <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        style="@style/floating_action_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:src="@drawable/ic_share_white_24dp"
        android:visibility="gone"
        app:backgroundTint="#FF9800"
        app:elevation="6dp"
        app:pressedTranslationZ="12dp" />

        <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="left|bottom|fill_vertical"
        android:layout_marginTop="0dp"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"></android.support.v4.view.ViewPager>
        <!--</FrameLayout>-->

        <!--<include layout="@layout/content_scrolling" />-->

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

    <RelativeLayout
        android:id="@+id/bannerView"
        android:layout_width="match_parent"
        android:layout_height="58dp"
        android:layout_gravity="bottom|center"
        android:background="@drawable/curved_white_with_blue_border"
        android:visibility="gone">

        <TextView
        android:id="@+id/bannerText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerInParent="true"
        android:layout_centerVertical="true"
        android:gravity="center"
        android:padding="3dp"
        android:text="Banner"
        android:visibility="gone" />

        <ImageView
        android:id="@+id/bannerImage"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:gravity="center"
        android:padding="3dp"
        android:scaleType="fitXY"
        android:visibility="gone" />

        <ImageView
        android:id="@+id/bannerClose"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:layout_centerVertical="true"
        android:src="@drawable/cross_icon" />
    </RelativeLayout>


    <LinearLayout
        android:id="@+id/socialTabs"
        android:layout_width="match_parent"
        android:layout_height="46dp"
        android:layout_gravity="bottom|center"
        android:layout_marginBottom="5dp"
        android:background="@color/White"
        android:orientation="horizontal"
        android:visibility="gone">

        <ImageView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:adjustViewBounds="true"
        android:src="@drawable/follow" />

        <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:background="@color/White">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="46dp"
            android:layout_gravity="center"
            android:gravity="center"
            android:paddingLeft="10dp"
            android:paddingRight="10dp"
            android:weightSum="3">

            <ImageView
            android:id="@+id/facebookImageView"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_weight="1"
            android:src="@drawable/fb_follow" />

            <ImageView
            android:id="@+id/googlePlusImageView"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_marginLeft="5dp"
            android:layout_marginRight="5dp"
            android:layout_weight="1"
            android:adjustViewBounds="true"
            android:src="@drawable/google_follow" />

            <ImageView
            android:id="@+id/twitterImageView"
            android:layout_width="30dp"
            android:layout_height="30dp"
            android:layout_weight="1"
            android:adjustViewBounds="true"
            android:src="@drawable/twitter_follow" />
        </LinearLayout>
        </FrameLayout>
    </LinearLayout>
    </FrameLayout>

    <ExpandableListView
    android:id="@+id/left_drawer"
    android:layout_width="265dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:background="#fff"
    android:choiceMode="singleChoice"
    android:divider="@null"
    android:dividerHeight="0dp"
    android:drawSelectorOnTop="true"
    android:groupIndicator="@null"
    android:scrollbars="@null" />

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

回答1:


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);
    }
}


来源:https://stackoverflow.com/questions/34524625/how-to-expand-appbarlayout-when-scrolling-down-reaches-at-top-of-the-recyclervie

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!