web-dev-qa-db-ja.com

下にスクロールしたときにAppBarLayoutを展開する方法はRecyclerViewの上部にあります

私は1つのAndroidアプリで、CoordinatorLayoutAppBarLayoutCollapsingToolbarLayoutを使用してアドバンス折りたたみバー機能を使用しています。

Recyclerviewを使用して、フラグメント内のアイテムの数を表示しています。 recyclerviewを上にスクロールすると、AppBarLayoutがスムーズに折りたたまれますが、下にスクロールしてrecyclerviewの最初の項目に到達すると、 `AppBarLayout 'を展開せずに自動的にスクロールを停止します。

次に、もう一度下にスクロールしてAppBarLayoutを表示する必要があります。したがって、私の要件は、recyclerviewの上部に到達したときに下にスクロールすると、 `AppBarLayout 'を展開する必要があるということです。

どうすればこれを行うことができますか。何か案が ?同じビデオをご覧ください https://www.dropbox.com/s/va5jk27ikytk​​5ax/app_collapsebar_issue.mp4?dl=

これが私のレイアウトです:-

<?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>
18
Kushminder Garg

サンプルアプリ をまとめたところですが、これはあなたが求めている動作を示しているようです。 AppBarは、停止して別のスワイプでRecyclerViewが開くのを待つのではなく、その下のAppBarが上にスクロールされるたびに自動的に展開されます。

最も関連性の高いコンポーネントは、カスタムRecyclerViewクラスにあります。私はいくつかの説明的なコメントを追加しました:

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