SwipeRefreshlayout基本使用及总结

作者: 落魄的安卓开发 | 来源:发表于2016-09-19 18:00 被阅读1385次

    1、SwipeRefreshlayout介绍:
    Google提供的官方的下拉刷新的控件,它只接受一个子组件:即需要刷新的那个组件(可以滑动比如:ScrollView、ListView、WebView、RecyclerView等)

    2、SwipeRefreshlayout基本使用:
    使用巨简单、以嵌套WebView为例子:
    布局代码:

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

    Activity中代码:

    mSwipe = (SwipeRefreshLayout) findViewById(R.id.swipelayout);
        /*
         * 设置进度条的颜色
         * 参数是一个可变参数、可以填多个颜色
         */
        mSwipe.setColorSchemeColors(Color.parseColor("#d7a101"),Color.parseColor("#54c745"),Color.parseColor("#f16161"),Color.BLUE,Color.YELLOW);
        /*
         * 设置下拉刷新的监听
         */
        mSwipe.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh() {
                wvTest.loadUrl("http://www.baidu.com");
                mSwipe.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        /*
                         * 加载完毕之后就关闭进度条
                         */
                        mSwipe.setRefreshing(false);
                    }
                }, 10000);
            }
        });
    

    3、滑动冲突问题:
    SwipeRefreshlayout在嵌套ListView、WebView同时,ListView、WebView外层还嵌套了一层ViewGroup就会出现滑动冲突的问题。在SwipeRefreshlayout和ViewPager结合使用的时候也会出现滑动冲突的问题。下面是解决方案:
    3.1 SwipeRefreshlayout嵌套ListView滑动冲突
    方案1、实现ListView的onScrollListener,判断firstVisibleItem == 0&&firstItem.getTop()即:ListView中可见的第一个item是否是第一个,且第一个距离顶部的距离为0,来设置SwipeLayout的

    mSwipe.setEnabled(enable);//true:可以下拉;false:不可下拉
    

    方案2:继承SwipeRefreshlayout,重写它的canChildScrollUp()方法
    原理:http://blog.csdn.net/zhongyifly/article/details/51519116

    public class SimpleSwipeRefreshLayout extends SwipeRefreshLayout {
      private View view;
      public SimpleSwipeRefreshLayout(Context context) {
        super(context);
      }
    
      public SimpleSwipeRefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
      }
    
      public void setViewGroup(View view) {
        this.view = view;
      }
    
      /**
       * ListView被嵌套
       */
      @Override
      public boolean canChildScrollUp() {
          if (view != null && view instanceof AbsListView) {
            final AbsListView absListView = (AbsListView) view;
            return absListView.getChildCount() > 0 && (absListView.getFirstVisiblePosition() > 0 || absListView.getChildAt(0).getTop() < absListView.getPaddingTop());
          }
          return super.canChildScrollUp();
      }
    }
    

    3.2 SwipeRefreshlayout嵌套ViewPager滑动冲突
    方案1:在ViewPager中解决,即:监听在viewpager上滑动的距离,如果 横向滑动距离>纵向滑动距离 设置setEnabled(false)禁止SwipeRefreshlayout下拉,否则setEnable(true),允许下拉刷新。

    /**记录ViewPager滑动的位置*/
    private int mLastX;
    private int mLastY;
    
    vpBanner.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int x = (int) event.getX();
                int y = (int) event.getY();
                int action = event.getAction();
                switch (action) {
                case MotionEvent.ACTION_MOVE:
                    int a = x - mLastX;
                    int b = y - mLastY;
                    if(Math.abs(a) > Math.abs(b)){
                        swipelayout.setEnabled(false);
                    }else{
                        swipelayout.setEnabled(true);
                    }
                    break;
                }
              
                mLastX = x;
                mLastY = y;
                return false;
            }
        });
    

    方案2:在自定义Layout extends SwipeRefreshlayout,重写它的onInterceptTouchEvent方法。

    private int mLastX;
    private int mLastY;
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        int x = (int) ev.getX();
        int y = (int) ev.getY();
        int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_MOVE:
                int a = x - mLastX;
                int b = y - mLastY;
                if(Math.abs(a) > Math.abs(b)){
                    setEnabled(false);
                }else{
                    setEnabled(true);
                }
                break;
            case MotionEvent.ACTION_UP:
                setEnabled(true);
                break;
        }
        mLastX = x;
        mLastY = y;
        return super.onInterceptTouchEvent(ev);
    }
    

    4、自动刷新功能
    即:进入页面,SwipeRefreshlayout的进度条弹出来,进行刷新功能;
    参考:http://www.2cto.com/kf/201508/434568.html

    /**
     * 自动刷新
     */
    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) {
        }
    }

    相关文章

      网友评论

        本文标题:SwipeRefreshlayout基本使用及总结

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