When switch fragment with SwipeRefreshLayout during refreshing, fragment freezes but actually still work

▼魔方 西西 提交于 2019-11-26 21:41:44

Well... After some struggling I eventually solved this problem by myself, in a tricky way...

I just need to add these in onPause() :

@Override
public void onPause() {
    super.onPause();
    ...

    if (mSwipeRefreshLayout!=null) {
        mSwipeRefreshLayout.setRefreshing(false);
        mSwipeRefreshLayout.destroyDrawingCache();
        mSwipeRefreshLayout.clearAnimation();
    }
}

This issue seems to still be occurring in appcompat 22.1.1. Wrapping the SwipeRefreshLayout inside a FrameLayout solved this for me

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v4.widget.SwipeRefreshLayout

    android:id="@+id/contentView"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/tweet_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/grey_300" />

</android.support.v4.widget.SwipeRefreshLayout>
</FrameLayout>

In addition to @zlm2012 answer, I noticed that this issue was reproduced under Support Library 21.0.0, but seems to be fixed right now at 21.0.3

The solution works, but I think it is better just put those lines into its own function, like:

public void terminateRefreshing() {
    mSwipeRefreshLayout.setRefreshing(false);
    mSwipeRefreshLayout.destroyDrawingCache();
    mSwipeRefreshLayout.clearAnimation();
}

and call when switching the fragment.

Fragment prevFrag = fragmentManager.findFragmentById(drawerContainerId);

if(prevFrag instanceof SwipeRefreshFragment) {
    ((SwipeRefreshFragment)prevFrag).terminateRefreshing();
}

fragmentManager.beginTransaction().replace(drawerContainerId, fragment).commit();

It works! Just remove the transition from your fragment replacement, in my case I removed the following from my code:

.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
Bishwajeet Biswas

Set clickable="true" in top parent layout... It may solve the problem.

For the time being, you can avoid the issue by:

public class FixedRefreshLayout extends SwipeRefreshLayout {

    private static final String TAG = "RefreshTag";
    private boolean selfCancelled = false;

    public FixedRefreshLayout(Context context) {
        super(context);
    }

    public FixedRefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected Parcelable onSaveInstanceState()
    {
        if(isRefreshing()) {
            clearAnimation();
            setRefreshing(false);
            selfCancelled = true;
            Log.d(TAG, "For hide refreshing");
        }
        return super.onSaveInstanceState();
    }

    @Override
    public void setRefreshing(boolean refreshing) {
        super.setRefreshing(refreshing);
        selfCancelled = false;
    }

    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        super.onWindowFocusChanged(hasWindowFocus);
        if(hasWindowFocus && selfCancelled) {
            setRefreshing(true);
            Log.d(TAG, "Force show refreshing");
        }
    }
}

This has the added advantage of resuming the animation incase you decide to not switch the fragment (coming from some menu). It also ties in with the internal animation to make sure that the refreshing animation does not return if the network refresh has already completed.

Terminate SwipeRefresh whenever navigation menu item is clicked. It worked.

private void selectItem(int position) {

       mSwipeRefreshLayout.setRefreshing(false);

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