How disable swiperefreshlayout when Recyclerview is not on the first item?

和自甴很熟 提交于 2019-12-02 08:28:40

问题


My android project includes a recyclerView that contains a list of cardViews, and also there is a swipeRefreshLayout on the top of this recyclerView. When I scroll down the list and pull up those cardViews, I just want to disable swipeRefreshLayout. In other word, when RecyclerView is not on the first item, and if the user wants to scrolling back to first item, it must not show swipeRefreshLayout.

I googled a lot about this issue and there are some solutions for this problem that overrides onScrollStateChanged method, but they not behave very smooth and still swipeRefreshLayout remains enabled in some situations.

EDIT 1: Following links are include some of these solutions I mentioned above:

https://stackoverflow.com/a/27042911/4257703

https://gist.github.com/NikolaDespotoski/1a6bb83dbae133f67812

Here is my xml layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="horizontal">

<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/swipe_refresh_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginTop="8dp"
            android:choiceMode="none"
            android:focusable="false"
            android:listSelector="@android:color/darker_gray" />

        <ImageView
            android:id="@+id/empty"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center" />
    </FrameLayout>

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

EDIT 2: Today I realized that my broblem is occured because of implementing Tabs and swipeRefreshLayout together. For refreshing the data of Fragment which contains RecyclerView, user must drag the page to bottom, and in other hand for switching between tabs, user must drag the screen to right or left. Due to this touch gestures, some bugs and lags occur in scrolling my list. Please help me to address this problem. Thanks a lot.


回答1:


Maybe I am late, but have a try to this solution:

mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
mLayoutManager = new LinearLayoutManager(getActivity());    // a LinearLayoutManager
mRecyclerView.setLayoutManager(mLayoutManager);             // setting layoutManager on our RecyclerView

// Adding ScrollListener to getting whether we're on First Item position or not
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        mSwipeRefreshLayout.setEnabled(mLinearLayoutManager.findFirstCompletelyVisibleItemPosition() == 0); // 0 is for first item position
    }
});

mSwipeRefreshLayout is your SwipeRefreshLayout

After putting above code, you'll be able to swipe only when your First item is visible.

Hope this helps! 😊




回答2:


Here is the fix:

public class SwipeRefreshLayoutToggleScrollListener extends RecyclerView.OnScrollListener {
private List<RecyclerView.OnScrollListener> mScrollListeners = new ArrayList<RecyclerView.OnScrollListener>();
private int mExpectedVisiblePosition = 0;
private SwipeRefreshLayout mSwipeLayout;

public SwipeRefreshLayoutToggleScrollListener(SwipeRefreshLayout swipeLayout) {
    mSwipeLayout = swipeLayout;
}
public void addScrollListener(RecyclerView.OnScrollListener listener){
    mScrollListeners.add(listener);
}
public boolean removeScrollListener(RecyclerView.OnScrollListener listener){
    return mScrollListeners.remove(listener);
}
public void setExpectedFirstVisiblePosition(int position){
    mExpectedVisiblePosition = position;
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
    super.onScrollStateChanged(recyclerView, newState);
    notifyScrollStateChanged(recyclerView,newState);
    LinearLayoutManager llm = (LinearLayoutManager) recyclerView.getLayoutManager();
    int firstVisible = llm.findFirstCompletelyVisibleItemPosition();
    if(firstVisible != RecyclerView.NO_POSITION)
        mSwipeLayout.setEnabled(firstVisible == mExpectedVisiblePosition);

}

@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
    super.onScrolled(recyclerView, dx, dy);
    notifyOnScrolled(recyclerView, dx, dy);
}
private void notifyOnScrolled(RecyclerView recyclerView, int dx, int dy){
    for(RecyclerView.OnScrollListener listener : mScrollListeners){
        listener.onScrolled(recyclerView, dx, dy);
    }
}
private void notifyScrollStateChanged(RecyclerView recyclerView, int newState){
    for(RecyclerView.OnScrollListener listener : mScrollListeners){
        listener.onScrollStateChanged(recyclerView, newState);
    }
}
}

for more info check this

URL:https://gist.github.com/NikolaDespotoski/1a6bb83dbae133f67812



来源:https://stackoverflow.com/questions/33103428/how-disable-swiperefreshlayout-when-recyclerview-is-not-on-the-first-item

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