SweepRefreshLayout загрузчик не поднимается, когда вытаскивает андроид

Я использовал SwipeRefreshLayout с recyclerview, он отлично работает во всех версиях Android, но в Kitkat, когда я вытаскиваю, тогда загрузчик SwipeRefreshLayout не поднимается, а также не обновляет данные recyclerview, а работает в lollipop

Я использую 'com.android.support:support-v4:22.2.1'

Изменить 1

SwipeRefreshLayout swipe_refresh;
swipe_refresh = (SwipeRefreshLayout)rootView.findViewById(R.id.swipe_refresh);

swipe_refresh.post(new Runnable() {
            @Override
            public void run() {
                swipe_refresh.setRefreshing(true);
            }
        });


swipe_refresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                // Loading more data..
                .....
                ....
                getData();

            }
        });

swipe_refresh.setColorSchemeResources(android.R.color.holo_blue_bright,
                android.R.color.holo_green_light,
                android.R.color.holo_orange_light,
                android.R.color.holo_red_light);

public void getData(){
    // Load data from web service...
    ...
    ...
    ...


    // After loading
    swipe_refresh.setRefreshing(false);

    // Set data to adapter
}

Код макета

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipe_refresh"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:background="@color/grey_100">

     <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

            <android.support.v7.widget.RecyclerView
                android:id="@+id/gv_feeds"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="9"
                android:scrollbars="vertical"/>

            <ProgressBar
            android:id="@+id/prog_load_more"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_gravity="center_horizontal"
            android:visibility="gone"/>

            </LinearLayout>

        </FrameLayout>

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

Ответы

Ответ 1

У меня была такая же проблема. Это похоже на то, что у вас нет вашего RecyclerView в качестве прямого дочернего элемента вашего SwipeRefreshLayout.

Мы исправили эту проблему, используя собственный SwipeRefreshLayout, такой как этот:

public class FixedSwipeRefreshLayout extends SwipeRefreshLayout {

    private RecyclerView recyclerView;

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

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

    public void setRecyclerView(RecyclerView recyclerView) {
        this.recyclerView = recyclerView;
    }

    @Override
    public boolean canChildScrollUp() {
        if (recyclerView!=null) {
            return recyclerView.canScrollVertically(-1);
        }

        return false;
    }

}

Затем вместо использования android.support.v4.widget.SwipeRefreshLayout используйте свой собственный "com.example.app.FixedSwipeRefreshLayout" следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<com.example.app.FixedSwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/swipe_refresh"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
...
</com.example.app.FixedSwipeRefreshLayout>

И наконец, когда вы получите дескриптор вашего SwipeRefreshLayout, используйте свой собственный и установите RecyclerView:

FixedSwipeRefreshLayout swipe_refresh;
swipe_refresh = (FixedSwipeRefreshLayout) rootView.findViewById(R.id.swipe_refresh);
RecyclerView mRecyclerView = (RecyclerView) rootView.findViewById(R.id.gv_feeds);
swipe_refresh.setRecyclerView(mRecyclerView);

Надеюсь, что это поможет.

Ответ 2

В соответствии с swipeRefreshDocumentation SwipeRefreshLayout не очень хорошо работает с макетом, который не прокручивается, если он добавлен внутри него: у вас есть 2 решения для этого:

1) измените свой макет, чтобы заставить swipeRefreshLayout иметь прямой дочерний элемент как recyclerView.

что-то вроде этого:

<?xml version="1.0" encoding="utf-8"?>

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:id="@+id/ll_HeaderProgress"
        android:background="@color/white_color_30">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            <android.support.v4.widget.SwipeRefreshLayout
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/swipe_refresh"
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="9"
               >
            <android.support.v7.widget.RecyclerView
                android:id="@+id/recyclerview_buzz"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scrollbars="vertical"/>
</android.support.v4.widget.SwipeRefreshLayout>
            <ProgressBar
                android:id="@+id/ll_footerProgress"
                android:layout_width="40dp"
                android:layout_height="40dp"
                android:layout_gravity="center_horizontal"
                android:visibility="gone"/>
        </LinearLayout>
    </FrameLayout>

2) Расширьте SwipeRefreshLayout с помощью прослушивателя, чтобы иметь возможность добавлять различные условия из классов, отображающих этот макет.

Что-то вроде следующего: RefreshSwipeRefreshLayout.java

public class RefreshSwipeRefreshLayout extends SwipeRefreshLayout {   
  private OnChildScrollUpListener mScrollListenerNeeded;

  public interface OnChildScrollUpListener {
    boolean canChildScrollUp();
  }

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

 /**
  * Listener that controls if scrolling up is allowed to child views or not
  */
  public void setOnChildScrollUpListener(OnChildScrollUpListener listener) {
    mScrollListenerNeeded = listener;   
  }

  @Override
  public boolean canChildScrollUp() {
    if (mScrollListenerNeeded == null) {
      Log.e(GeneralSwipeRefreshLayout.class.getSimpleName(), "listener is not defined!");
    }
    return mScrollListenerNeeded != null && mScrollListenerNeeded.canChildScrollUp();
  }
}

а затем выполните это в классе, который отобразит SwipeRefreshLayout, содержащий макет recyclerView, вы можете сделать что-то вроде этого:

mSwipeLayout.setOnChildScrollUpListener(new OnChildScrollUpListener() {
  @Override
  public boolean canChildScrollUp() {
    return   ((LinearLayoutManager)mRecyclerView.getLayoutManager()).findFirstVisibleItemPosition().getFirstVisiblePosition() > 0 || 
           mRecyclerView.getChildAt(0) == null || 
           mRecyclerView.getChildAt(0).getTop() < 0;
  }

});

Также не забудьте изменить его в xml

Ответ 3

Вы пробуйте этот путь

   listView.setOnScrollListener(new OnScrollListener() {

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
        boolean enable = false;
        if(listView != null && listView.getChildCount() > 0){
            // check if the first item of the list is visible
            boolean firstItemVisible = listView.getFirstVisiblePosition() == 0;
            // check if the top of the first item is visible
            boolean topOfFirstItemVisible = listView.getChildAt(0).getTop() == 0;
            // enabling or disabling the refresh layout
            enable = firstItemVisible && topOfFirstItemVisible;
        }
        swipeRefreshLayout.setEnabled(enable);
    }});

Ответ 4

Возможно, я опоздаю на это, но у меня была такая же проблема, но я добавил:

swipe_refresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
    @Override
    public void onRefresh() {
        // Loading more data..
        .....
        ....
        getData();

        //make sure to set it to false as this will be set it to true when onRefresh is triggered
        swipe_refresh.setRefreshing(false);
    }
});