一、SwipeRefreshLayout简介
SwipeRefreshLayout作为谷歌官方推荐的下拉刷新控件,在实际开发中,经常都会遇到下拉刷新、上拉加载更多的情形。,该控件集成自ViewGroup在support-v4兼容包下。
- SwipeRefrshLayout常用的几个方法如下:
isRefreshing():判断当前的状态是否是刷新状态。
setColorSchemeResources(int… colorResIds):设置下拉进度条的颜色主题,参数为可变参数,并且是资源id,可以设置多种不同的颜色,每转一圈就显示一种颜色。
setOnRefreshListener(SwipeRefreshLayout.OnRefreshListener listener):设置监听,需要重写onRefresh()方法,顶部下拉时会调用这个方法,在里面实现请求数据的逻辑,设置下拉进度条消失等等。
setProgressBackgroundColorSchemeResource(int colorRes):设置下拉进度条的背景颜色,默认白色。
setRefreshing(boolean refreshing):设置刷新状态,true表示正在刷新,false表示取消刷新。
使用SwipeRefrshLayout要想达到刷新的目的,首先需要在这个布局里包裹可以滑动的子控件,如ScrollView、ListView、RecyclerView等,并且只能有一个子控件。然后在代码里设置OnRefreshListener设置监听,最后在监听里设置刷新时的数据获取就可以了。
二、简单示例
上面是SwipeRefreshLayout主要方法的作用,其实使用起来非常的简单,接下来先通过一个简单示例来学习SwipeRefreshLayout+RecyclerView的使用方法。
1、在src/main/res/layout/目录下创建activity_main.xml文件,代码如下所示:
<?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/swiperefreshlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
从布局文件中看,在SwipeRefreshLayout控件里面加入RecyclerView子元素。
2、在src/main/res/layout/目录下创建上拉加载和RecyclerView中Item布局文件
上拉加载布局文件activity_main_foot.xml
<?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="wrap_content">
<android.support.v4.widget.ContentLoadingProgressBar
android:id="@+id/pb_progress"
style="?android:attr/progressBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
</LinearLayout>
RecyclerView中Item布局文件activity_main_item.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardElevation="2dp"
android:layout_margin="5dp">
<TextView
android:id="@+id/textItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="45dp"
android:text="测试1"
android:gravity="center"/>
</android.support.v7.widget.CardView>
3、创建一个MyViewHolder类继承RecyclerView.ViewHolder,代码如下所示
public class MyViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
public MyViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.textItem);
}
public void setTextViewText(String text){
textView.setText(text);
}
}
4、创建一个上拉加载FootViewHolder类继承 RecyclerView.ViewHolder,代码如下所示:
public class FootViewHolder extends RecyclerView.ViewHolder {
ContentLoadingProgressBar contentLoadingProgressBar;
public FootViewHolder(View itemView) {
super(itemView);
contentLoadingProgressBar = itemView.findViewById(R.id.pb_progress);
}
}
5、创建一个MyAdapter适配器类继承RecyclerView.Adapter<RecyclerView.ViewHolder>
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private final static int TYPE_CONTENT = 0;//正常内容
private final static int TYPE_FOOTER = 1;//加载View
private OnLoadMoreListener mOnLoadMoreListener;
private List<Integer> listData = new ArrayList<>();
private Context context;
public MyAdapter(Context context,List<Integer> listData , OnLoadMoreListener mOnLoadMoreListener){
this.context = context;
this.listData = listData;
this.mOnLoadMoreListener = mOnLoadMoreListener;
}
@Override
public int getItemViewType(int position) {
if (position == listData.size() && mOnLoadMoreListener.isAllScreen()) {
return TYPE_FOOTER;
}
return TYPE_CONTENT;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_FOOTER) {
View view = LayoutInflater.from(context).inflate(R.layout.activity_main_foot, parent, false);
return new FootViewHolder(view);
} else {
View view = LayoutInflater.from(context).inflate(R.layout.activity_main_item, parent, false);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
if (getItemViewType(position) == TYPE_FOOTER) {
} else {
MyViewHolder viewHolder = (MyViewHolder) holder;
viewHolder.setTextViewText("第" + position + "行");
}
}
@Override
public int getItemCount() {
return listData.size() + 1;
}
}
5、定义一个抽象类实现上拉加载,上拉加载其实主要是继承RecyclerView.OnScrollListener,主要是监听RecyclerView滑动事件,判断它是否滑动了最底部,如果滑动最底部还有数据就去加载数据。代码如下所示:
public abstract class OnLoadMoreListener extends RecyclerView.OnScrollListener {
private int countItem;
private int lastItem;
private boolean isScrolled = false;//是否可以滑动
private boolean isAllScreen = false;//是否充满全屏
private RecyclerView.LayoutManager layoutManager;
/**
* 加载接口
*
* @param countItem 总数量
* @param lastItem 最后显示的position
*/
protected abstract void onLoading(int countItem, int lastItem);
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if (newState==SCROLL_STATE_IDLE){
Log.d("test","SCROLL_STATE_IDLE,空闲");
}
else if (newState==SCROLL_STATE_DRAGGING){
Log.d("test","SCROLL_STATE_DRAGGING,拖拽");
}
else if (newState==SCROLL_STATE_SETTLING){
Log.d("test","SCROLL_STATE_SETTLING,固定");
}
else{
Log.d("test","其它");
}
//拖拽或者惯性滑动时isScolled设置为true
if (newState == SCROLL_STATE_DRAGGING || newState == SCROLL_STATE_SETTLING) {
isScrolled = true;
isAllScreen =true;
} else {
isScrolled = false;
}
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (recyclerView.getLayoutManager() instanceof LinearLayoutManager) {
layoutManager = recyclerView.getLayoutManager();
countItem = layoutManager.getItemCount();
lastItem = ((LinearLayoutManager) layoutManager).findLastCompletelyVisibleItemPosition();
}
if (isScrolled && countItem != lastItem && lastItem == countItem - 1) {
onLoading(countItem, lastItem);
}
}
public boolean isAllScreen(){
return isAllScreen;
}
}
6、然后在我们MainActivity.java中去使用,代码如下所示
public class MainActivity extends AppCompatActivity {
private static final String TAG = "wq892373445";
private MyAdapter myAdapter;
private LinearLayoutManager layoutManager;
private SwipeRefreshLayout refreshLayout;
private RecyclerView recyclerView;
private Handler handler;
private List<Integer> listData = new ArrayList<>();
private int count = 0;
private OnLoadMoreListener mOnLoadMoreListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
getData("reset");
handler = new Handler();
layoutManager = new LinearLayoutManager(this);
refreshLayout = findViewById(R.id.swiperefreshlayout);
recyclerView = findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
mOnLoadMoreListener=new OnLoadMoreListener() {
@Override
protected void onLoading(int countItem, int lastItem) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
getData("loadMore");
}
}, 3000);
}
};
myAdapter = new MyAdapter(this,listData,mOnLoadMoreListener);
recyclerView.setAdapter(myAdapter);
recyclerView.addOnScrollListener(mOnLoadMoreListener);
//设置下拉时圆圈的颜色(可以尤多种颜色拼成)
refreshLayout.setColorSchemeResources(android.R.color.holo_blue_light,
android.R.color.holo_red_light,
android.R.color.holo_orange_light);
//设置下拉时圆圈的背景颜色(这里设置成白色)
refreshLayout.setProgressBackgroundColorSchemeResource(android.R.color.white);
refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
getData("refresh");
}
});
}
private void getData(final String type) {
if ("reset".equals(type)) {
listData.clear();
count = 0;
for (int i = 0; i < 3; i++) {
count += 1;
listData.add(count);
}
}
else if ("refresh".equals(type)) {
listData.clear();
count = 0;
for (int i = 0; i < 13; i++) {
count += 1;
listData.add(count);
}
myAdapter.notifyDataSetChanged();
if (refreshLayout.isRefreshing()) {
refreshLayout.setRefreshing(false);
}
Toast.makeText(getApplicationContext(), "刷新完毕", Toast.LENGTH_SHORT).show();
} else {
for (int i = 0; i < 3; i++) {
count += 1;
listData.add(count);
}
myAdapter.notifyDataSetChanged();
if (refreshLayout.isRefreshing()) {
refreshLayout.setRefreshing(false);
}
Toast.makeText(getApplicationContext(), "加载完毕", Toast.LENGTH_SHORT).show();
}
}
}
上述代码首先获取布局控件,先设置RecyclerView显示的管理器和适配器,然后再设置SwipeRefreshLayout。