美文网首页
问题:解决SwipeRefreshLayout与其嵌套控件的冲突

问题:解决SwipeRefreshLayout与其嵌套控件的冲突

作者: 玉圣 | 来源:发表于2018-01-05 14:40 被阅读199次

直接集成SwipeRefreshLayout控件,重写相关方法:
代码如下:

import android.content.Context;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ListView;

import com.xs.lib.core.util.MyLog;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import cn.daoyibigu.R;


/**
 * 解决SwipeRefreshLayout与其嵌套控件的冲突
 * @author hyk
 *
 */
public class MySwipeRefreshLayout extends SwipeRefreshLayout {

    private ListView mListView;
    private OnLoadListener mOnLoadListener;

    // private float firstTouchY;
    // private float lastTouchY;

    private float startY;
    private float startX;
    // 记录viewPager是否拖拽的标记
    private boolean mIsVpDragger;
    private int mTouchSlop;

    private boolean isLoading = false;

    private boolean scrollFlag = false;// 标记是否滑动

    public MySwipeRefreshLayout(Context context) {
        this(context, null);
        init(context);
    }

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

    // 四种颜色变换
    private void init(Context context) {
        this.setColorSchemeResources(R.color.google_blue, R.color.google_green, R.color.google_red,
                R.color.google_yellow);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
    }

    // set the child view of RefreshLayout,ListView
    public void setChildView(ListView mListView) {
        this.mListView = mListView;
        this.mListView.setOnScrollListener(new OnScrollListener() {

            @Override
            public void onScrollStateChanged(AbsListView listView, int scrollState) {
                switch (scrollState) {
                    // 当不滚动时
                    case OnScrollListener.SCROLL_STATE_IDLE:// 是当屏幕停止滚动时
                        scrollFlag = false;
                        break;
                    case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:// 滚动时
                        scrollFlag = true;
                        break;
                    case OnScrollListener.SCROLL_STATE_FLING:// 是当用户由于之前划动屏幕并抬起手指,屏幕产生惯性滑动时
                        scrollFlag = true;
                        break;
                }
            }

            @Override
            public void onScroll(AbsListView listView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                if (null != mOnLoadListener) {
                    if (!isLoading && visibleItemCount > 0 && (firstVisibleItem + visibleItemCount == totalItemCount)) {
                        setLoading(true);
                    }
                }
            }
        });
    }

    public void setLoading(boolean loading) {
        if (mListView == null)
            return;
        isLoading = loading;
        if (loading) {
            if (isRefreshing()) {
                setRefreshing(false);
            }
            mListView.setSelection(mListView.getAdapter().getCount() - 1);
            mOnLoadListener.onLoad(loading);
        }
        // else {
        // firstTouchY = 0;
        // lastTouchY = 0;
        // }
    }

    /**
     * 自动刷新
     */
    public void autoRefresh() {
        try {
            Field mCircleView = SwipeRefreshLayout.class.getDeclaredField("mCircleView");
            mCircleView.setAccessible(true);
            View progress = (View) mCircleView.get(this);
            progress.setVisibility(VISIBLE);

            Method setRefreshing = SwipeRefreshLayout.class.getDeclaredMethod("setRefreshing", boolean.class,
                    boolean.class);
            setRefreshing.setAccessible(true);
            setRefreshing.invoke(this, true, true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setOnLoadListener(OnLoadListener loadListener) {
        mOnLoadListener = loadListener;
    }

    public void removeOnLoadListener() {
        mOnLoadListener = null;
    }

    public interface OnLoadListener {
        void onLoad(boolean isStart);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                // 记录手指按下的位置
                startY = ev.getY();
                startX = ev.getX();
                // 初始化标记
                mIsVpDragger = false;
                break;
            case MotionEvent.ACTION_MOVE:
                // 如果viewpager正在拖拽中,那么不拦截它的事件,直接return false;
                if(mIsVpDragger) {
                    return false;
                }

                // 获取当前手指位置
                float endY = ev.getY();
                float endX = ev.getX();
                float distanceX = Math.abs(endX - startX);
                float distanceY = Math.abs(endY - startY);
                // 如果X轴位移大于Y轴位移,那么将事件交给viewPager处理。
                if(distanceX > mTouchSlop && distanceX > distanceY) {
                    mIsVpDragger = true;
                    return false;
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                // 初始化标记
                mIsVpDragger = false;
                break;
        }
        // 如果是Y轴位移大于X轴,事件交给swipeRefreshLayout处理。
        return super.onInterceptTouchEvent(ev);
    }

}

相关文章

网友评论

      本文标题:问题:解决SwipeRefreshLayout与其嵌套控件的冲突

      本文链接:https://www.haomeiwen.com/subject/cdqsnxtx.html