web-dev-qa-db-ja.com

Android:CollapsingToolbarLayoutとSwipeRefreshLayoutがスタックする

CollapsingToolbarLayout、RecyclerView、およびSwipeRefreshLayoutを一緒に使用します。

Xml:

<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/drawer_layout"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:fitsSystemWindows="true">

<Android.support.design.widget.CoordinatorLayout
    Android:id="@+id/coordinator_layout"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:fitsSystemWindows="true">

<Android.support.design.widget.AppBarLayout
    Android:id="@+id/appbar"
    Android:layout_width="match_parent"
    Android:layout_height="@dimen/collapse_toolbar_height"
    Android:fitsSystemWindows="true"
    Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <Android.support.design.widget.CollapsingToolbarLayout
        Android:id="@+id/collapsing_toolbar"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        app:contentScrim="?attr/colorPrimary"
        Android:fitsSystemWindows="true"
        app:expandedTitleMarginStart="48dp"
        app:expandedTitleMarginEnd="64dp"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

        <ImageView
            Android:id="@+id/toolbar_image"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:scaleType="centerCrop"
            Android:fitsSystemWindows="true"
            app:layout_collapseMode="parallax" />

        <include
            layout="@layout/activity_main_toolbar"/>

    </Android.support.design.widget.CollapsingToolbarLayout>
</Android.support.design.widget.AppBarLayout>

    <Android.support.v4.widget.SwipeRefreshLayout
        Android:id="@+id/swipe_container"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <cz.yetanotherview.webcamviewer.app.helper.EmptyRecyclerView
            Android:id="@+id/mainList"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:scrollbars="vertical" />
    </Android.support.v4.widget.SwipeRefreshLayout>

    <Android.support.design.widget.FloatingActionButton
        Android:id="@+id/floating_action_button"
        Android:layout_height="wrap_content"
        Android:layout_width="wrap_content"
        app:layout_anchor="@id/appbar"
        app:layout_anchorGravity="bottom|right|end"
        Android:layout_margin="16dp"
        app:fabSize="mini"
        Android:src="@drawable/ic_action_edit"
        Android:onClick="assignSelectedWebCamsToCategory"/>

    <com.github.clans.fab.FloatingActionMenu
        Android:id="@+id/floating_action_menu"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:layout_gravity="bottom|end"
        Android:paddingRight="10dp"
        Android:paddingBottom="8dp"
        Android:paddingLeft="10dp"
        fab:menu_shadowColor="#37000000"
        fab:menu_colorNormal="#DA4336"
        fab:menu_colorPressed="#E75043"
        fab:menu_colorRipple="#99FFFFFF"
        fab:menu_icon="@drawable/fab_add"
        fab:menu_buttonSpacing="10dp"
        fab:menu_labels_textColor="@color/very_dark_grey"
        fab:menu_labels_textSize="14sp"
        fab:menu_labels_colorNormal="@color/white"
        fab:menu_labels_colorPressed="@color/next_grey"
        fab:menu_labels_colorRipple="#99FFFFFF"
        fab:menu_labels_margin="8dp"
        fab:menu_backgroundColor="@color/black_transparent">

        <com.github.clans.fab.FloatingActionButton
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:src="@drawable/ic_action_content_import"
            fab:fab_size="mini"
            fab:fab_label="@string/pref_import_from_server"
            fab:fab_colorNormal="@color/white"
            app:fab_colorPressed="@color/next_grey"
            app:fab_colorRipple="#99FFFFFF"
            Android:onClick="showSelectionDialog"/>

        <com.github.clans.fab.FloatingActionButton
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:src="@drawable/ic_action_content_manually"
            fab:fab_size="mini"
            fab:fab_label="@string/create_manually"
            fab:fab_colorNormal="@color/white"
            app:fab_colorPressed="@color/next_grey"
            app:fab_colorRipple="#99FFFFFF"
            Android:onClick="showAddDialog"/>

        <com.github.clans.fab.FloatingActionButton
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:src="@drawable/ic_action_content_suggestion"
            fab:fab_size="mini"
            fab:fab_label="@string/submit_suggestion"
            fab:fab_colorNormal="@color/white"
            app:fab_colorPressed="@color/next_grey"
            app:fab_colorRipple="#99FFFFFF"
            Android:onClick="showSuggestionDialog"/>

    </com.github.clans.fab.FloatingActionMenu>
</Android.support.design.widget.CoordinatorLayout>

<include
    layout="@layout/activity_main_drawer"/>
</Android.support.v4.widget.DrawerLayout>

コード:

    swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
    swipeRefreshLayout.setOnRefreshListener(this);

スワイプ更新アクションを許可する方法のみツールバーのレイアウトが折りたたまれている場合完全に展開およびscrollview(recyclerview)? Google+やInboxアプリケーションのような同様の動作。

間違った:

enter image description here

良い:

enter image description here

53
Tomas

最後に、

SwipeRefreshLayoutが機能することがわかりました「ハック」なしサポートライブラリバージョンから23.1.1

レイアウトで使用するだけです:

 <Android.support.v4.widget.SwipeRefreshLayout
    Android:id="@+id/swipe_refresh_layout"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <Android.support.v7.widget.RecyclerView
            Android:id="@+id/recycler_view"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:scrollbars="vertical" />
</Android.support.v4.widget.SwipeRefreshLayout>

コード内:

SwipeRefreshLayout swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);
swipeRefreshLayout.setColorSchemeResources(R.color.green, R.color.red, R.color.yellow);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
    @Override
    public void onRefresh() {
       //Your refresh code here
    }
});

使用することを忘れないでください:

swipeRefreshLayout.setRefreshing(false);

コードロジックを使用した後;)

24
Tomas

更新:この問題は、サポートライブラリの最新バージョン(23.1.1+)で解決されました。サポートライブラリの古いバージョンを使用している場合は、アップグレードするか、読み続けてください。

サポートライブラリの古いバージョンを使用している場合、オフセット変更リスナーをAppBarLayoutに追加して、それに応じてレイアウトを更新するスワイプを有効または無効にします。ここで利用可能な追加コード:

https://Gist.github.com/blackcj/001a90c7775765ad5212

関連する変更:

public class MainActivity extends AppCompatActivity implements AppBarLayout.OnOffsetChangedListener {
    ...

    private AppBarLayout appBarLayout;
    private SwipeRefreshLayout mSwipeRefreshLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ...
        mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.contentView);
        appBarLayout = (AppBarLayout) findViewById(R.id.appBarLayout);

    }

    @Override
    public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
        //The Refresh must be only active when the offset is zero :
        mSwipeRefreshLayout.setEnabled(i == 0);
    }

    @Override
    protected void onResume() {
        super.onResume();
        appBarLayout.addOnOffsetChangedListener(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        appBarLayout.removeOnOffsetChangedListener(this);
    }
}
90
blackcj

正しく理解できたら、ツールバーを展開した後にのみ更新を開始しますか?そのため、最初にCollapsingToolbarLayoutを開いてから、更新を開始する必要があります。次のコードで管理しました。

     <Android.support.design.widget.CoordinatorLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
        xmlns:app="http://schemas.Android.com/apk/res-auto"
        Android:id="@+id/coordinator_layout"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:fitsSystemWindows="true">

        <Android.support.design.widget.AppBarLayout
            Android:id="@+id/app_bar_layout"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:fitsSystemWindows="true"
            Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

            <Android.support.design.widget.CollapsingToolbarLayout
                Android:id="@+id/collapsing_toolbar"
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:fitsSystemWindows="true"
                app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed">

                <LinearLayout
                    Android:layout_width="match_parent"
                    Android:layout_height="wrap_content"
                    Android:orientation="vertical">
                      <!--PUT HERE WHAT EVER YOU WANT TO COLLAPSE, A TOOLBAR, ETC...-->
                </LinearLayout>
            </Android.support.design.widget.CollapsingToolbarLayout>
        </Android.support.design.widget.AppBarLayout>
     <Android.support.v4.widget.SwipeRefreshLayout
        Android:id="@+id/swipe_refresh_layout"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

            <Android.support.v7.widget.RecyclerView
                Android:id="@+id/recycler_view"
                Android:layout_width="match_parent"
                Android:layout_height="match_parent"
                Android:clipToPadding="false"
                Android:fadeScrollbars="false"
                Android:scrollbars="vertical"
                app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    </Android.support.v4.widget.SwipeRefreshLayout>
</Android.support.design.widget.CoordinatorLayout>   

次に、フラグメント/アクティビティでAppBarLayout.OnOffsetChangedListenerを実装します(ツールバーが完全に展開されると更新が有効になります)。

    @Override
    public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
        if (collapsingToolbarLayout.getHeight() + verticalOffset < 2 * ViewCompat.getMinimumHeight(collapsingToolbarLayout)) {
            swipeRefreshLayout.setEnabled(false);
        } else {
            swipeRefreshLayout.setEnabled(true);
        }
    }

@blackcj回答のようにonPause()およびonResume()をオーバーライドします。

  @Override
    public void onResume() {
        super.onResume();
        appBarLayout.addOnOffsetChangedListener(this);
    }

    @Override
    public void onPause() {
        super.onPause();
        appBarLayout.removeOnOffsetChangedListener(this);
    }

次に、LinearLayoutManagerをrecyclerViewに設定します。

    LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
    layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    recyclerView.setLayoutManager(layoutManager);

私にとってこれは魅力として機能し、最初にappBarlayoutが展開されてから、swipeRefreshLayoutが更新をトリガーします。

11
hkop

Support Library 23.2.0を使用して問題を解決するには、RecyclerViewをSwipeRefreshLayoutのメインの子にする必要がありました。 SwipeRefreshLayout内にレイアウトを含むが含まれていると修正できませんでした

<Android.support.v4.widget.SwipeRefreshLayout
        Android:id="@+id/my_swipeRefreshLayout"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent">

        <!--<include layout="@layout/my_RecyclerView_layout"/> issue for me here -->

        <Android.support.v7.widget.RecyclerView
            Android:id="@+id/my_recyclerView"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent">
        </Android.support.v7.widget.RecyclerView>

    </Android.support.v4.widget.SwipeRefreshLayout>
1
Rensodarwin