一、自定义SwpieRefreshLayout简介
相信很多人都用过Android官方刷新控件SwipeRefreshLayout,不过如果直接使用可能无法满足日常开发的需求。有很多我们需要的操作,谷歌官方没有提供API给我们,例如进入页面自动刷新,上拉加载数据等操作。
这次我继承SwipeRefreshLayout控件,扩展并封装上拉加载操作和进入页面自动刷新操作。
按照惯例咋们来看看最终效果图
二、自定义SwpieRefreshLayout的使用方法
看完效果图之后就来说一说使用方法,不过在这之前,我还是贴一张此Demo的项目结构图
自定义控件只有一个JAVA文件,没有使用额外的XML布局文件
需要使用的同学,可以直接将CustomSwipeRefreshLayout文件拷贝到自己项目工程中即可。
1、只是用进入页面刷新功能。
(1)先实现CustomSwipeRefreshLayout.CustomOnRefreshListener下拉刷新接口。
(2)设置setCustomOnRefreshListener(this)注册监听器。
(3)调用进入页面刷新方法setAutoRefresh()。
(4)重写onRefresh()方法,在这里面实现业务逻辑操作。
效果图如下具体代码如下:
效果图如下
效果如下图:
package sms.edward.per.myapplication;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ArrayAdapter;
import android.widget.ListView;
/**
* 自定义SwpieRefreshLayout(进入页面自动刷新,下拉刷新,上拉加载更多)
* <p/>
* 此Demo博客地址:
*
* @author Edward
*/
public class MainActivity extends Activity implements CustomSwipeRefreshLayout.CustomOnRefreshListener {
private CustomSwipeRefreshLayout customSwipeRefreshLayout;
private ListView listView;
private ArrayAdapter<String> adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.list_view);
customSwipeRefreshLayout = (CustomSwipeRefreshLayout) findViewById(R.id.swipe_refresh);
//实例化监听器,必须
customSwipeRefreshLayout.setCustomOnRefreshListener(this);
//设置进入页面刷新,可选
customSwipeRefreshLayout.setAutoRefresh();
}
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1);
for (int i = 0; i < 5; i++) {
adapter.add(String.valueOf(i));
}
customSwipeRefreshLayout.setRefreshing(false);
listView.setAdapter(adapter);
}
}, 1500);
}
}
效果图如下
2、使用进入页面刷新,点击加载功能。
(1)先实现CustomSwipeRefreshLayout.CustomOnRefreshListener下拉刷新接口和CustomSwipeRefreshLayout.CustomLoadMoreListener加载接口。
(2)设置setCustomOnRefreshListener(this),setCustomLoadMoreListener(this)注册监听器。
(3)调用进入页面刷新方法setAutoRefresh()。
(4)重写onRefresh()方法,在这里面实现业务逻辑操作。
(5)重写loadMore()方法,在这里面实现"加载更多"操作。
具体代码如下:
效果图如下
package sms.edward.per.myapplication;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ArrayAdapter;
import android.widget.ListView;
/**
* 自定义SwpieRefreshLayout(进入页面自动刷新,下拉刷新,上拉加载更多)
* <p/>
* 此Demo博客地址:
*
* @author Edward
*/
public class MainActivity extends Activity implements CustomSwipeRefreshLayout.CustomOnRefreshListener, CustomSwipeRefreshLayout.CustomLoadMoreListener {
private CustomSwipeRefreshLayout customSwipeRefreshLayout;
private ListView listView;
private ArrayAdapter<String> adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.list_view);
customSwipeRefreshLayout = (CustomSwipeRefreshLayout) findViewById(R.id.swipe_refresh);
customSwipeRefreshLayout.setCustomOnRefreshListener(this);
customSwipeRefreshLayout.setCustomLoadMoreListener(this);
//设置进入页面刷新,可选 customSwipeRefreshLayout.setAutoRefresh();
}
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1);
for (int i = 0; i < 5; i++) {
adapter.add(String.valueOf(i));
}
customSwipeRefreshLayout.setRefreshing(false);
listView.setAdapter(adapter);
}
}, 1500);
}
@Override
public void loadMore() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 2; i++) {
adapter.add(String.valueOf(i));
}
customSwipeRefreshLayout.setFinishLoadMoreText();
adapter.notifyDataSetChanged();
}
}, 1500);
}
}
好啦,关于此自定义控件的最简单用法已经介绍完毕。接下来说说样式的使用。
3、自定义SwipeRefreshLayout控件的样式使用
在SwipeRefreshLayout的源代码中,我写了一个SwipeRefreshParamsModel类,这个类用来定义底部"加载更多"的样式。
如果你对这个
原生的样式看起来很不顺眼,你可以new一个SwipeRefreshParamsModel类,使用各种SwipeRefreshParamsModel.setXXX方法,设置属性。将其传入给setSwipeRefreshParamsModel方法即可。
演示代码如下:
package sms.edward.per.myapplication;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ArrayAdapter;
import android.widget.ListView;
/**
* 自定义SwpieRefreshLayout(进入页面自动刷新,下拉刷新,上拉加载更多)
* <p/>
* 此Demo博客地址:
*
* @author Edward
*/
public class MainActivity extends Activity implements CustomSwipeRefreshLayout.CustomOnRefreshListener, CustomSwipeRefreshLayout.CustomLoadMoreListener {
private CustomSwipeRefreshLayout customSwipeRefreshLayout;
private ListView listView;
private ArrayAdapter<String> adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.list_view);
customSwipeRefreshLayout = (CustomSwipeRefreshLayout) findViewById(R.id.swipe_refresh);
customSwipeRefreshLayout.setCustomOnRefreshListener(this);
customSwipeRefreshLayout.setCustomLoadMoreListener(this);
//设置自动刷新
customSwipeRefreshLayout.setAutoRefresh();
//SwipeRefreshParamsModel的使用方法。
CustomSwipeRefreshLayout.SwipeRefreshParamsModel swipeRefreshParamsModel = new CustomSwipeRefreshLayout.SwipeRefreshParamsModel();
//设置字体大小
swipeRefreshParamsModel.setTextSize(25);
//设置字体颜色
swipeRefreshParamsModel.setSetTextColor(Color.parseColor("#ffffff"));
//设置底部背景
swipeRefreshParamsModel.setSetContainerBackgroundColor(Color.parseColor("#31b2f7"));
//设置底部按钮未点击前的提示文本
swipeRefreshParamsModel.setStartRefreshText("疯狂加载中...");
//设置底部按钮点击之后的提示文本
swipeRefreshParamsModel.setFinishRefreshText("点我刷新");
//设置进度框的宽度和高度
swipeRefreshParamsModel.setProgressBarWidthSize(30);
swipeRefreshParamsModel.setProgressBarHeightSize(30);
//设置所有属性之后,将swipeRefreshParamsModel传去给此方法
customSwipeRefreshLayout.setSwipeRefreshParamsModel(swipeRefreshParamsModel);
}
@Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1);
for (int i = 0; i < 5; i++) {
adapter.add(String.valueOf(i));
}
customSwipeRefreshLayout.setRefreshing(false);
listView.setAdapter(adapter);
}
}, 1500);
}
@Override
public void loadMore() {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 2; i++) {
adapter.add(String.valueOf(i));
}
customSwipeRefreshLayout.setFinishLoadMoreText();
adapter.notifyDataSetChanged();
}
}, 1500);
}
}
效果如下图:
最后一个方法我差点忘记说了,CustomSwipeRefreshLayout类提供了一个isOpenToastHint方法,这个方法用来提示用户此时正在执行下拉刷新操作,不能点击加载。或者此时正在执行加载操作,不能执行下拉刷新
也就一行代码的事
//开启提示
customSwipeRefreshLayout.setIsOpenToastHint(true);
效果如图所示
三、自定义SwipeRefreshLayout控件源代码
好了来到源代码这一块,不过本人不打算讲解了,该注意的地方都用注释写了。有兴趣的同学可以看看^_^
package sms.edward.per.myapplication;
import android.content.Context;
import android.graphics.Color;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
/**
* description:自定义SwipeRefreshLayout(进入页面自动刷新,下拉刷新,点击加载更多)
* <p/>
* 在底部加一个Button按钮,来点击“加载更多”
* <p/>
* 此demo在Android2.3.7版本运行通过
* <p/>
* author:Edward
* <p/>
* 2015/10/17
*/
public class CustomSwipeRefreshLayout extends SwipeRefreshLayout implements SwipeRefreshLayout.OnRefreshListener {
private Context mContext;
private ListView listView;
//“加载更多”监听事件
private CustomLoadMoreListener customLoadMoreListener;
//下拉刷新监听事件
private CustomOnRefreshListener customOnRefreshListener;
//标记当前正在执行“加载更多”操作,(false表示没有正在加载,true表示正在加载)
private boolean isLoadMore = false;
//底部“加载更多”容器
private RelativeLayout container;
//“加载更多”按钮TextView
private TextView loadMoreTextView;
//“加载更多”进度框
private ProgressBar progressBar;
//此Model用来设置整个CustomSwipeRefreshLayout自定义控件的参数
private SwipeRefreshParamsModel swipeRefreshParamsModel;
//是否开启Toast提示,默认为不开启
private boolean isOpenToastHint = false;
//
private RelativeLayout.LayoutParams lp, lp1;
//设置开启Toast
public void setIsOpenToastHint(boolean isOpenToastHint) {
this.isOpenToastHint = isOpenToastHint;
}
/**
* 设置底部容器的参数
*
* @param swipeRefreshParamsModel
*/
public void setSwipeRefreshParamsModel(SwipeRefreshParamsModel swipeRefreshParamsModel) {
this.swipeRefreshParamsModel = swipeRefreshParamsModel;
}
/**
* 设置刷新回调监听器
*
* @param customOnRefreshListener
*/
public void setCustomOnRefreshListener(CustomOnRefreshListener customOnRefreshListener) {
this.customOnRefreshListener = customOnRefreshListener;
}
/**
* 设置加载更多回调监听器
*
* @param customLoadMoreListener
*/
public void setCustomLoadMoreListener(CustomLoadMoreListener customLoadMoreListener) {
this.customLoadMoreListener = customLoadMoreListener;
}
public CustomSwipeRefreshLayout(Context context) {
this(context, null);
}
public CustomSwipeRefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
setOnRefreshListener(this);
//如果没有设置SwipeRefreshParamsModel,则实例化初始值
if (this.swipeRefreshParamsModel == null) {
this.swipeRefreshParamsModel = new SwipeRefreshParamsModel();
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
//了解一下控件绘制流程
if (listView == null) {
//获取当前布局孩子的总数
int count = getChildCount();
//获取子类布局控件
if (count > 0) {
View view = getChildAt(0);
if (view instanceof ListView) {
listView = (ListView) view;
//判断用户是否设置过“加载更多”监听事件
if (this.customLoadMoreListener != null) {
setClickLoadMore();
}
}
}
}
}
/**
* 设置加载更多按钮
*/
public void setClickLoadMore() {
//创建一个container容器
container = new RelativeLayout(mContext);
container.setOnClickListener(new loadMoreClickListener());
//设置间距
container.setPadding(swipeRefreshParamsModel.getLeftPadding(), swipeRefreshParamsModel.getTopPadding(), swipeRefreshParamsModel.getRightPadding(), swipeRefreshParamsModel.getBottomPadding());
container.setBackgroundColor(swipeRefreshParamsModel.getSetContainerBackgroundColor());
loadMoreTextView = new TextView(mContext);
loadMoreTextView.setTextColor(swipeRefreshParamsModel.getSetTextColor());
loadMoreTextView.setTextSize(swipeRefreshParamsModel.getTextSize());
loadMoreTextView.setText(swipeRefreshParamsModel.getFinishRefreshText());
lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.CENTER_IN_PARENT);
loadMoreTextView.setId(Integer.valueOf(1));
loadMoreTextView.setLayoutParams(lp);
container.addView(loadMoreTextView);
//默认为隐藏状态
progressBar = new ProgressBar(mContext);
//设置进度框的大小
lp1 = new RelativeLayout.LayoutParams(swipeRefreshParamsModel.getProgressBarWidthSize(), swipeRefreshParamsModel.getProgressBarHeightSize());
lp1.addRule(RelativeLayout.LEFT_OF, 1);
lp1.addRule(RelativeLayout.CENTER_VERTICAL);
progressBar.setLayoutParams(lp1);
container.addView(progressBar);
progressBar.setVisibility(View.GONE);
if (listView != null) {
//将整个container容器添加到ListView的底部
listView.addFooterView(container);
}
}
/**
* 设置结束加载文本
*/
public void setFinishLoadMoreText() {
loadMoreTextView.setText(swipeRefreshParamsModel.getFinishRefreshText());
//重新隐藏进度框
progressBar.setVisibility(View.GONE);
//将加载更多的标记设为false(加载完毕)
isLoadMore = false;
}
/**
* 加载按钮点击事件
*/
public class loadMoreClickListener implements OnClickListener {
@Override
public void onClick(View view) {
//没有执行下拉刷新,加载更多的监听事件不为空。
if (!isRefreshing() && customLoadMoreListener != null) {
isLoadMore = true;
loadMoreTextView.setText(swipeRefreshParamsModel.getStartRefreshText());
//将隐藏的ProGressBar显示出来
progressBar.setVisibility(View.VISIBLE);
customLoadMoreListener.loadMore();
} else {
if (isOpenToastHint)
Toast.makeText(mContext, swipeRefreshParamsModel.getPullUpText(), Toast.LENGTH_SHORT).show();
}
}
}
/**
* 设置进入页面自动刷新
*/
public void setAutoRefresh() {
//判断是否已经设置了setRefreshing(true)
if (isRefreshing()) {
//如果已经设置将其改变为false
setRefreshing(false);
}
post(new Thread(new Runnable() {
@Override
public void run() {
setRefreshing(true);
}
}));
onRefresh();
}
@Override
public void onRefresh() {
//回调刷新控件,如果监听器为空并且正在处于加载更多的过程中,则不刷新
if (customOnRefreshListener != null && !isLoadMore) {
customOnRefreshListener.onRefresh();
} else {
if (isOpenToastHint) {
Toast.makeText(mContext, swipeRefreshParamsModel.getPullDownText(), Toast.LENGTH_SHORT).show();
}
setRefreshing(false);
}
}
/**
* 下拉刷新回调监听事件
*/
public interface CustomOnRefreshListener {
void onRefresh();
}
/**
* 加载更多回调监听事件
*/
public interface CustomLoadMoreListener {
void loadMore();
}
/**
* 用来设置整个SwipeRefreshLayout控件参数的Model,可提供给用户直接修改。
*/
public static class SwipeRefreshParamsModel {
private float textSize = 14;
private String finishRefreshText = "加载更多";
private String startRefreshText = "正在加载...";
//设置进度框的大小
private int progressBarWidthSize = 50, progressBarHeightSize = 50;
private int setContainerBackgroundColor = Color.parseColor("#e8ebee");
private int setTextColor = Color.GRAY;
private int leftPadding = 20, topPadding = 20, rightPadding = 0, bottomPadding = 20;
private String pullDownText = "正在加载中,请稍后再试...";
private String pullUpText = "正在刷新中,请稍后再试...";
public float getTextSize() {
return textSize;
}
public void setTextSize(float textSize) {
this.textSize = textSize;
}
public String getFinishRefreshText() {
return finishRefreshText;
}
public void setFinishRefreshText(String finishRefreshText) {
this.finishRefreshText = finishRefreshText;
}
public String getStartRefreshText() {
return startRefreshText;
}
public void setStartRefreshText(String startRefreshText) {
this.startRefreshText = startRefreshText;
}
public int getProgressBarWidthSize() {
return progressBarWidthSize;
}
public void setProgressBarWidthSize(int progressBarWidthSize) {
this.progressBarWidthSize = progressBarWidthSize;
}
public int getProgressBarHeightSize() {
return progressBarHeightSize;
}
public void setProgressBarHeightSize(int progressBarHeightSize) {
this.progressBarHeightSize = progressBarHeightSize;
}
public int getSetContainerBackgroundColor() {
return setContainerBackgroundColor;
}
public void setSetContainerBackgroundColor(int setContainerBackgroundColor) {
this.setContainerBackgroundColor = setContainerBackgroundColor;
}
public int getSetTextColor() {
return setTextColor;
}
public void setSetTextColor(int setTextColor) {
this.setTextColor = setTextColor;
}
public void setLeftPadding(int leftPadding, int topPadding, int rightPadding, int bottomPadding) {
this.leftPadding = leftPadding;
this.topPadding = topPadding;
this.rightPadding = rightPadding;
this.bottomPadding = bottomPadding;
}
public int getLeftPadding() {
return leftPadding;
}
public int getTopPadding() {
return topPadding;
}
public int getRightPadding() {
return rightPadding;
}
public int getBottomPadding() {
return bottomPadding;
}
public String getPullDownText() {
return pullDownText;
}
public void setPullDownText(String pullDownText) {
this.pullDownText = pullDownText;
}
public String getPullUpText() {
return pullUpText;
}
public void setPullUpText(String pullUpText) {
this.pullUpText = pullUpText;
}
}
}
四、结束
结束了,谢谢各位捧场^_^。