SwipeRefreshLayout вытягивает многократное поведение (SDK 23)

У меня SwipeRefreshLayout как это:

.xml

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

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

.java

private SwipeRefreshLayout swipeLayout;
swipeLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swipe_refresh_layout);
        swipeLayout.setColorSchemeColors(getResources().getColor(R.color.primary_color));
        swipeLayout.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh() {
                refreshContent();
            }
        });

Это позволяет мне тянуть swipeRefresh несколько раз, а круговая анимация становится странной, иногда она остается на экране без кручения:

введите описание изображения здесь

При первом нажатии он появляется немного сверху, при втором нажатии он уменьшается немного по сравнению с изображением.

Как отключить многократное нажатие swipeRefresh, пока оно уже освежает? Я предполагаю, что этого не происходит ниже sdk 23. Я использую buildTool 23, targetSdk 23, support-v4: 23, appcompat-v7: 23.

Обновление: этого не происходит, если я использую ListView вместо RecyclerView.

Ответ 1

Эта проблема была введена в support-v4 23.0.0 и вызвана новой вложенной функциональностью прокрутки, не проверяющей isRefreshing().

Вы должны расширить SwipeRefreshLayout и переопределить функцию onStartNestedScroll:

@Override
public boolean onStartNestedScroll(View child, View target, int nestedScrollAxes) {
    return !isRefreshing() && super.onStartNestedScroll(child, target, nestedScrollAxes);
}

Ответ 2

"support-v4: 23.1.0" уже исправлена ​​эта ошибка.

Ответ 3

Это похоже на ошибку в библиотеке поддержки appcompat-v7, которая была представлена ​​в выпуске 23.0.0. В качестве обходного пути вы можете отключить SwipeRefreshLayout в обратном вызове OnRefreshListener # onRefresh и снова включить его при загрузке данных:

private class MyOnRefreshListener implements SwipeRefreshLayout.OnRefreshListener {

    @Override
    public void onRefresh() {
        swipeRefreshLayout.setEnabled(false);
        load();
    }

    private void onLoaded() {
        swipeRefreshLayout.setEnabled(true);
        swipeRefreshLayout.setRefreshing(false);
    }
}

Ответ 4

добавить переменную boolean, чтобы проверить ваш список для обновления в данный момент.

if (!refreshing)
refreshContent();

Ответ 5

вы можете подклассифицировать SwipeRefreshLayout, предоставляя свою собственную реализацию canChildScrollUp()

 @Override
public boolean canChildScrollUp() {
   if (isRefreshing()) {
        return true;
   }
   return false;
}

конечно, вы должны проверить, показывает ли ваш просмотр ресайклером уже его первый ребенок и соответственно возвращает значение

Ответ 6

При завершении обновления данных вам необходимо вызвать mSwipeRefreshLayout.stopRefreshing().

public void refreshContent() {
...
//end of your "refresh" code

if(mSwipeRefreshLayout.isRefreshing())
    mSwipeRefreshLayout.stopRefreshing()
}