CoordinatorLayout AppBarLayout combined with pull-down refresh and pull-up to load more sliding conflicts

Keywords: Android Java

Reprint: https://blog.csdn.net/axuanqq/article/details/51144295

if (appBarLayout != null)  
            appBarLayout.addOnOffsetChangedListener(this);  
@Override  
public void onOffsetChanged(AppBarLayout appBarLayout, int i) {  
    super.onOffsetChanged(appBarLayout, i);  
    if (srlLayout == null) return;  
    srlLayout.setEnabled(i >= 0||isSlideToBottom(recyclerview) ? true : false);  
}  

i> = 0 indicates that appBarLayout is fully displayed: the touch event that can refresh the control needs to be enabled = true;
For the isSlideToBottom method, please See Monitor at bottom of recyclerview scrolling

When recyclerView scrolls to the bottom, the touch event enable=true of the refresh control needs to be enabled;

Mask the scope of refresh control: when appBarLayout is scrolling, the recylerView does not scroll to the bottom

There is another way to achieve this:

@Override  
public void onOffsetChanged(AppBarLayout appBarLayout, int i) {  
    super.onOffsetChanged(appBarLayout, i);  
    LogUtils.d("-------->off:" + i + "  ScrollRange:" + appBarLayout.getTotalScrollRange() + "  height:" + appBarLayout.getHeight());  
}  

It can be observed that I > = 0 means appBarLaoyut is fully open
When i==-appBarLayout.getTotalScrollRange(), it means that appBarLayout is completely closed or folded
So: i==-appBarLayout.getTotalScrollRange() can also be judged and distributed to the refresh control

A tool class is given by the way:

<pre name="code" class="java">
import android.support.design.widget.AppBarLayout;
import android.support.v7.widget.RecyclerView;

/**
 * @author xuanyouwu
 * @email xuanyouwu@163.com
 * @time 2016-04-13 16:25
 */
public class DesignViewUtils {

    /**
     * AppBarLayout Full open
     *
     * @param verticalOffset
     * @return
     */
    public static boolean isAppBarLayoutOpen(int verticalOffset) {
        return verticalOffset >= 0;
    }

    /**
     * AppBarLayout Closed or folded
     *
     * @param appBarLayout
     * @param verticalOffset
     * @return
     */
    public static boolean isAppBarLayoutClose(AppBarLayout appBarLayout, int verticalOffset) {
        return appBarLayout.getTotalScrollRange() == Math.abs(verticalOffset);
    }

    /**
     * RecyclerView Scroll to the last full display at the bottom
     *
     * @param recyclerView
     * @return
     */
    public static boolean isSlideToBottom(RecyclerView recyclerView) {
        if (recyclerView == null) return false;
        if (recyclerView.computeVerticalScrollExtent() + recyclerView.computeVerticalScrollOffset() >= recyclerView.computeVerticalScrollRange())
            return true;
        return false;
    }

    /**
     * RecyclerView Scroll to top
     *
     * @param recyclerView
     * @return
     */
    public static boolean isSlideToTop(RecyclerView recyclerView) {
        return recyclerView.computeVerticalScrollOffset() <= 0;
    }
}

Perfect solution to refresh case:

<pre name="code" class="java">
import android.support.design.widget.AppBarLayout;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;

import com.kekeclient.widget.design.DesignViewUtils;

/**
 * @author xuanyouwu
 * @email xuanyouwu@163.com
 * @time 2016-04-15 11:20
 * <p/>
 * Resolve nested nestScrolling appbar refresh conflict
 */
public class SwipyAppBarScrollListener extends RecyclerView.OnScrollListener implements AppBarLayout.OnOffsetChangedListener {
    private AppBarLayout appBarLayout;
    private RecyclerView recyclerView;
    private ViewGroup refreshLayout;
    private boolean isAppBarLayoutOpen = true;
    private boolean isAppBarLayoutClose;

    public SwipyAppBarScrollListener(AppBarLayout appBarLayout, ViewGroup refreshLayout, RecyclerView recyclerView) {
        this.appBarLayout = appBarLayout;
        this.refreshLayout = refreshLayout;
        this.recyclerView = recyclerView;
        disptachScrollRefresh();
    }


    private void disptachScrollRefresh() {
        if (this.appBarLayout != null && this.recyclerView != null && refreshLayout != null) {
            this.appBarLayout.addOnOffsetChangedListener(this);
            this.recyclerView.addOnScrollListener(this);
        }
    }

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

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        dispatchScroll();
    }

    @Override
    public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
        isAppBarLayoutOpen = DesignViewUtils.isAppBarLayoutOpen(verticalOffset);
        isAppBarLayoutClose = DesignViewUtils.isAppBarLayoutClose(appBarLayout, verticalOffset);
        dispatchScroll();
    }

    private void dispatchScroll() {
        if (this.recyclerView != null && this.appBarLayout != null && this.refreshLayout != null) {
            //Non rolling
            if (!(ViewCompat.canScrollVertically(recyclerView, -1) || ViewCompat.canScrollVertically(recyclerView, 1))) {
                refreshLayout.setEnabled(isAppBarLayoutOpen);
            } else//Can roll
            {
                if (isAppBarLayoutOpen || isAppBarLayoutClose) {
                    if (!ViewCompat.canScrollVertically(recyclerView, -1) && isAppBarLayoutOpen) {
                        refreshLayout.setEnabled(true);
                    } else if (isAppBarLayoutClose && !ViewCompat.canScrollVertically(recyclerView, 1)) {
                        refreshLayout.setEnabled(true);
                    } else {
                        refreshLayout.setEnabled(false);
                    }
                } else {
                    refreshLayout.setEnabled(false);
                }
            }
        }
    }
}

Usage:

recyclerview.addOnScrollListener(new SwipyAppBarScrollListener(appBarLayout, srlLayout, recyclerview));

Posted by iconicCreator on Wed, 01 Apr 2020 18:54:49 -0700