控件SwipeRefreshLayout解析

1,004 阅读4分钟

这是我参与11月更文挑战的第14天,活动详情查看:2021最后一次更文挑战

Android下拉刷新控件SwipeRefreshLayout解析

SwipeRefreshLayout是Google在support v4 19.1版本的library更新的一个下拉刷新组件,实现刷新效果更方便。我们知道现在存在很多种类的下拉刷新,所以谷歌在推出SwipeRefreshLayout控件也是希望为了进一步的规范android市场吧!随着现在版本的不断更新,谷歌推出的SwipeRefreshLayout的效果也在发生着变化,主要变化点在系统5.0之后,SwipeRefreshLayout重新改变下拉的样式。

在使用之前我们需要更新我们的android-support-v4.jar版本在19.1之前,这样我们才能使用。所以下面我们就透过源码分析下SwipeRefreshLayout。先看看此类的介绍:

/**
	 * The SwipeRefreshLayout should be used whenever the user can refresh the
	 * contents of a view via a vertical swipe gesture. The activity that
	 * instantiates this view should add an OnRefreshListener to be notified
	 * whenever the swipe to refresh gesture is completed. 
	 * ...
	 * This layout should be made the parent of the view that will be refreshed as a
	 * result of the gesture and can only support one direct child. This view will
	 * also be made the target of the gesture and will be forced to match both the
	 * width and the height supplied in this layout. The SwipeRefreshLayout does not
	 * provide accessibility events; instead, a menu item must be provided to allow
	 * refresh of the content wherever this gesture is used.
	 * </p>
	 */
	public class SwipeRefreshLayout extends ViewGroup{
		...
	}

上面的意思就是说,当用户通过swipe gesture(刷卡手势)进行刷新的时候,都可以使用SwipeRefreshLayout进行数据刷新。同时呢?我们应该在展现该控件的activity中添加OnRefreshListener接口来控制刷新什么时候完成。同时我们发现SwipeRefreshLayout是继承在ViewGroup,不是我们常见的继承ListView,所以它的实现逻辑和ListView是没关系的,这样就解放了我们使用ListView,不需要复杂的逻辑判断处理。SwipeRefreshLayout应该是需要刷新的View的父控件,它只能有一个子View。同时它的直接子View要具有滑动功能。

通过上面的注释,我们队SwipeRefreshLayout的基本使用有了一个了解,下面我们看看它有哪些方法需要我们注意:
1、public void setProgressViewOffset(boolean scale, int start, int end),用来设置刷新控件的起始位置和终止位置。下面是scale的属性值解释。

scale:
	 Set to true if there is no view at a higher z-order than
      where the progress spinner is set to appear

2、public void setProgressViewEndTarget(boolean scale, int end),设置刷新控件的终止位置,scale属性设置同上。

3、 public void setSize(int size),设置刷新控件的大小,系统默认给我们提供两个选项:SwipeRefreshLayout.LARGE(大图)和SwipeRefreshLayout.DEFAULT(小图)。

4、public void setOnRefreshListener(OnRefreshListener listener),用于设置我们的下拉刷新回调事件,很重要的一个方法。

5、 public void setRefreshing(boolean refreshing),设置是否进行刷新,刷新完毕后设置为false,则刷新控件消失。

6、public void setProgressBackgroundColor(int colorRes),设置刷新控件的背景色。

param colorRes Resource id of the color.

7、public void setColorSchemeResources(int... colorResIds),设置刷新控件动画中的颜色。参数为资源id

8、public void setColorSchemeColors(int... colors),设置刷新控件动画中的颜色。参数为颜色值。

9、 public boolean isRefreshing()判断是否正在进行刷新状态。

10、public void setRefreshing(boolean refreshing),设置控件是否进行刷新

以上就是我们比较常见的几个方法,其中5-10方法是我们比较常用的。下面我们就来进行使用下。

我们在api21上进行使用,所以是新版的刷新效果。我们在android studio中建立一个名称为swiperefreshdemo的module来进行测试。
1、看下布局文件:

<android.support.v4.widget.SwipeRefreshLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:id="@+id/swipeRefresh"
    tools:context=".MainActivity">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:id="@+id/tv_state"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/app_name"
            android:textColor="#ff0000"
            android:padding="20dp"/>
        </ScrollView>

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

2、MainActivity中的代码:

public class MainActivity extends ActionBarActivity {
    private SwipeRefreshLayout swipeRefreshLayout;
    private TextView tv_state;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv_state = (TextView) findViewById(R.id.tv_state);
        swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefresh);
        swipeRefreshLayout.setColorSchemeResources(android.R.color.holo_blue_light, android.R.color.holo_red_light, android.R.color.holo_orange_light, android.R.color.holo_green_light);
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
            //刷新5秒
            mHandler.sendEmptyMessageDelayed(0,5000);
            }
        });
    }

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
           tv_state.setText("正在刷新");
            //刷新完成后停止刷新
           swipeRefreshLayout.setRefreshing(false);
        }
    };
	}

很简单的使用,直接看效果图: textview

效果是不是很nice,也是现在很多app比较流行的下拉刷新。现在让我们看看嵌套ListView的使用。

ListView下拉刷新

1、布局文件

<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:id="@+id/swipeRefresh"
    tools:context="test.dsw.com.swiperefreshdemo.ListViewActivity">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

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

2、在ListViewActivity中处理代码:

public class ListViewActivity extends ActionBarActivity {
	    private SwipeRefreshLayout mSwipeRefreshLayout;
	    private ListView listView;
	    private MyAdapter adapter;
	    List<ImageInfor> list = new ArrayList<>();
	    @Override
	    protected void onCreate(Bundle savedInstanceState) {
	        super.onCreate(savedInstanceState);
	        setContentView(R.layout.activity_list_view);
	        initData();
	        mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefresh);
	        listView = (ListView) findViewById(R.id.listView);
	        adapter = new MyAdapter(list);
	        listView.setAdapter(adapter);
	        mSwipeRefreshLayout.setColorSchemeResources(android.R.color.holo_blue_light, android.R.color.holo_red_light,
	                android.R.color.holo_orange_light, android.R.color.holo_green_light);
	        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
	            @Override
	            public void onRefresh() {
	                adapter.addList(list);
	                mHandler.sendEmptyMessageDelayed(0,5000);
	            }
	        });
	    }
	
	    private Handler mHandler = new Handler() {
	        @Override
	        public void handleMessage(Message msg) {
	            Toast.makeText(getApplication(),"数据更新完毕",Toast.LENGTH_SHORT).show();
	            //刷新完成后停止刷新
	            mSwipeRefreshLayout.setRefreshing(false);
	        }
	    };

    ...
	}

且看效果图: listView

通过以上的两个案例,我们可以发现,其实SwipeRefreshLayout就是一个ViewGroup,我们可以为任何想要的控件包裹起来进行下拉刷新。这样就降低了刷新和控件之间的耦合性,提高了灵活性。我们现在完整的演示下这两个案例。 all 以上就是在api21上的使用效果,对于4.0系统的效果我们就不演示了,直接上个图供大家参考吧!