Android 在片段事务期间在 swipeRefreshLayout 上设置刷新(false)时片段两次

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

我的 activity 中有两个片段(我使用片段事务在它们之间导航):

  1. 科目列表
  2. 学科详情 - 成绩列表

主题片段布局:

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

swipeRefreshLayout 的侦听器是 activity。它触发一个 AsyncTask 下载新数据,通知片段数据已更改并隐藏 swipeRefreshLayout。

onPostExecute 方法中有问题的部分:

...

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

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

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

它通常有效,但在这种情况下无效:

在这种情况下,主题片段就挂在那里,两个片段都在 activity。

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

如何在 refreshLayout 上 setRefreshing(false) 并避免两次获取主题片段?

更改您的代码,参考 stack overflow

上的答案
  public class YourFragment extends Fragment {
    SwipeRefreshLayout swipeLayout;

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        String[] values = new String[] { "Android List View",
                "Adapter implementation",
                "Simple List View In Android",
                "Create List View Android",
                "Android Example",
                "List View Source Code",
                "List View Array Adapter",
                "Android Example List View",
                "Android List View",
                "Adapter implementation",
                "Simple List View In Android",
                "Create List View Android",
                "Android Example",
                "List View Source Code",
                "List View Array Adapter",
                "Android Example List View",
                "Android List View",
                "Adapter implementation",
                "Simple List View In Android",
                "Create List View Android",
                "Android Example",
                "List View Source Code",
                "List View Array Adapter",
                "Android Example List View"
        };

        final SwipeRefreshLayout swipeView = (SwipeRefreshLayout)view. findViewById(R.id.refresher);

        swipeView.setEnabled(false);
        ListView lView = (ListView) view.findViewById(R.id.your_list_view);
        ArrayAdapter<String> adp = new ArrayAdapter<String>(view.getContext(),
                android.R.layout.simple_list_item_1, android.R.id.text1, values);
        lView.setAdapter(adp);

        swipeView.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                swipeView.setRefreshing(true);
                ( new Handler()).postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        swipeView.setRefreshing(false);

                    }
                }, 3000);
            }
        });

        lView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView absListView, int i) {

            }

            @Override
            public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if (firstVisibleItem == 0)
                    swipeView.setEnabled(true);
                else
                    swipeView.setEnabled(false);
            }
        });

    }

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


    }

我在 SO 上发现了一个类似的问题:

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

我使用 appcompat-v7:23.3.0。这个答案对我有用:

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

我的 swipelayout.setOnRefresh 电话两次都遇到同样的问题。

基本上原因不在 swipelayout.setOnRefreshLisetener 我正在加载一些数据,当我的 recyclerview 到达终点时 swipelayout.setOnRefreshListener 我也在做同样的事情。

所以我为消除错误所做的是我只是注释掉了 swipelayout.setOnRefreshListener 中的加载方法。

 swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {

                if (mLatestAdapter.getItemCount() > 0) {

                    mLatestAdapter.removeAllItems();
                    mPresenter.resetPagination();
                   // mPresenter.loadMoreItems(false);//commentwed this line 


                }
            }
        });

这就是我在我的 recyclerview 中所做的

 mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                // Here get the child count, item count and visibleitems
                // from layout manager

                visibleItemCount = mLayoutManager.getChildCount();
                totalItemCount = mLayoutManager.getItemCount();
                pastVisiblesItems = mLayoutManager
                        .findFirstVisibleItemPosition();
                // Now check if userScrolled is true and also check if
                // the item is end then update recycler view and set
                // userScrolled to false
                if (userScrolled
                        && (visibleItemCount + pastVisiblesItems) == totalItemCount) {
                    userScrolled = false;

                    if (!getBaseActivity().isNetworkConnected()) {
                        getBaseActivity().onError("Internet is not Connected");
                        return;
                    }
                    Log.wtf(TAG, "onScrolled: reach end" );
                    mPresenter.loadMoreItems(true);//here it is after removing all items from recyclerview it calls automatically

                }
            }

            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);

                // If scroll state is touch scroll then set userScrolled
                // true
                if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
                    userScrolled = true;
                }
            }
        });