SwipeRefreshLayout源码解析
SwipeRefreshLayout简介
SwipeRefreshLayout是Android support v4库中的一个控件,用于让开发者快速实现下拉刷新效果。
简单应用
下面是SwipeRefreshLayout的一个简单的应用示例,效果如下:
示例代码包含两个布局文件以及MainActivity。
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.swt369.swiperefreshlayouttest.MainActivity">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:layout_marginTop="5dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true">
<ListView
android:id="@+id/list_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
list_item:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
</TextView>
MainActivity.java:
package com.example.swt369.swiperefreshlayouttest;
import android.os.AsyncTask;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.LinkedList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private List<String> mList;
private ArrayAdapter<String> mAdapter;
private SwipeRefreshLayout refreshLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
refreshLayout = (SwipeRefreshLayout)findViewById(R.id.swipe_refresh_layout);
ListView listView = (ListView)findViewById(R.id.list_view);
mList = new LinkedList<>();
int count = 5;
while(count-- > 0){
mList.add(String.valueOf(mList.size()));
}
mAdapter = new ArrayAdapter<>(this,R.layout.list_item,mList);
listView.setAdapter(mAdapter);
refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
refreshOperation();
}
});
}
private void refreshOperation(){
new RefreshTask().execute();
}
private class RefreshTask extends AsyncTask<Void,Void,Void>{
@Override
protected Void doInBackground(Void... params) {
try {
int count = 3;
while(count-- > 0){
mList.add(String.valueOf(mList.size()));
}
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
mAdapter.notifyDataSetChanged();
refreshLayout.setRefreshing(false);
}
}
}
总结一下的话,SwipeRefreshLayout的使用分以下几个步骤:
1. 在布局文件中添加SwipeRefreshLayout,并将需要实现下拉刷新的目标控件置于其中。
2. 利用findViewById获取SwipeRefreshLayout与目标控件的引用。
3. 通过SwipeRefreshLayout.setOnRefreshListener()方法为SwipeRefreshLayout提供刷新逻辑。刷新逻辑的结尾要调用SwipeRefreshLayout的setRefreshing(false)方法。
源码解析
下面以源码为基础,对SwipeRefreshLayout的实现做一个解析。
构造器
public SwipeRefreshLayout(Context context) {
this(context, null);
}
public SwipeRefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);
//利用ViewConfiguration获取滑动阈值(即判定为滑动所需的距离)
m