IT TIP

Android : CollapsingToolbarLayout 및 SwipeRefreshLayout이 중단됨

itqueen 2021. 1. 10. 19:47
반응형

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 애플리케이션과 유사한 동작입니다.

잘못된:

여기에 이미지 설명 입력

좋은:

여기에 이미지 설명 입력


업데이트 : 이 문제는 최신 버전의 지원 라이브러리 (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);
    }
}

드디어,

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

코드 로직을 사용한 후;)


제대로 이해했다면 툴바가 확장 된 후에 만 ​​새로 고침을 시작하고 싶 겠죠? 따라서 먼저 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이 새로 고침을 트리거합니다.


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>

위 답변 에 적합 AppCompatActivity하지만, 당신이 사용하는 경우 Fragment다음 다음 코드는 당신을 도울 것입니다.

그냥 NestedScrollViewXML에 넣어fragment

<android.support.v4.widget.NestedScrollView 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="fill_vertical"
    android:clipToPadding="false"
    android:isScrollContainer="false"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <!-- A RecyclerView with some commonly used attributes -->
        <android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/album_timeline_swipe_refresh_layout"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <android.support.v7.widget.RecyclerView
                android:id="@+id/album_timeline_recyclerview"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:clickable="true" />
        </android.support.v4.widget.SwipeRefreshLayout>

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

참조 URL : https://stackoverflow.com/questions/30779667/android-collapsingtoolbarlayout-and-swiperefreshlayout-get-stuck

반응형