Search code examples
androidandroid-fragmentsswiperefreshlayout

Android fragment twice when setRefreshing(false) on swipeRefreshLayout during fragment transaction


I have two fragments in my activity (I navigate between them using fragment transaction):

  1. list of subjects
  2. subject detail - list of grades

Subject Fragment layout:

<android.support.v4.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/refresher"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

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

The listener for the swipeRefreshLayout is the activity. It triggers an AsyncTask which downloads new data, notifies fragments that the data has changed and hides the swipeRefreshLayout.

The problematic part of the onPostExecute method:

...

try {
    formatData();
} catch (JSONException e) {
    e.printStackTrace();
}

View refresher = findViewById(R.id.refresher);
((SwipeRefreshLayout) refresher).setRefreshing(false);

marksFragment.notifyUpdate(activity);
subjectsFragment.notifyUpdate(activity);

It normally works, but not in this case:

  • I pull to refresh data
  • I navigate to the subject detail (using fragment transaction)
  • The setRefreshing method is called during the fragment transaction

In this case the subject fragments just hangs there and both fragments are in the activity.

Code of SubjectFragment:

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    ((SwipeRefreshLayout) view.findViewById(R.id.refresher)).setOnRefreshListener((SwipeRefreshLayout.OnRefreshListener) activity);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.subjects_fragment, null);
}

How can I setRefreshing(false) on a refreshLayout and avoid getting the subjects fragment twice?


Solution

  • I found a similar question on SO:

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

    I use appcompat-v7:23.3.0. This answer worked for me:

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

    So my subject fragment layout looks like this:

    <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
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/refresher"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <ListView
                android:id="@android:id/list"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>
    
        </android.support.v4.widget.SwipeRefreshLayout>
    </FrameLayout>