把SmartRefreshLayout加入到项目:
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.scwang.smartrefresh:SmartRefreshLayout:1.0.2-alpha-5'
在自定义的Application文件里初始化:
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
initRefreshViewLayout();
}
private void initRefreshViewLayout() {
MyRefreshLayout.init();
}
}
自定义个继承自SmartRefreshLayout的MyRefreshLayout文件:
public class MyRefreshLayout extends SmartRefreshLayout {
public static void init() {
// 指定全局的下拉Header
SmartRefreshLayout.setDefaultRefreshHeaderCreater(new DefaultRefreshHeaderCreater() {
@Override
public RefreshHeader createRefreshHeader(Context context, RefreshLayout layout) {
return new MyRefreshHeader(context);
}
});
// 指定全局的上拉Footer
SmartRefreshLayout.setDefaultRefreshFooterCreater(new DefaultRefreshFooterCreater() {
@NonNull
@Override
public RefreshFooter createRefreshFooter(Context context, RefreshLayout layout) {
return new ClassicsFooter(context);
}
});
}
public MyRefreshLayout(Context context) {
super(context);
initView(context);
}
public MyRefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
public MyRefreshLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
private void initView(Context context) {
setReboundDuration(300); // 设置回弹动画时长
setPrimaryColorsId(R.color.white); // 主题色
setEnableAutoLoadmore(false); // 设置是否监听列表在滚动到底部时触发加载事件
}
// 下拉/上拉完成
public void complete() {
if (mState == RefreshState.Loading) {
finishLoadmore();
} else {
finishRefresh();
}
}
}
创建个MyRefreshHeader文件, 在这里做自定义的动画:
public class MyRefreshHeader extends RelativeLayout implements RefreshHeader {
private CircleProgressView mCircleProgressView;
private TextView mTextView;
private ImageView mArrow;
private boolean isArrowDown = false;
public MyRefreshHeader(Context context) {
super(context);
this.initView(context, null, 0);
}
public MyRefreshHeader(Context context, AttributeSet attrs) {
super(context, attrs);
this.initView(context, attrs, 0);
}
public MyRefreshHeader(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.initView(context, attrs, defStyleAttr);
}
private void initView(Context context, AttributeSet attrs, int defStyleAttr) {
setMinimumHeight(dp2px(context, 80));
LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.addRule(CENTER_IN_PARENT);
View headerView = View.inflate(context, R.layout.my_refresh_header, null);
mCircleProgressView = (CircleProgressView) headerView.findViewById(R.id.circleProgressView);
mTextView = (TextView) headerView.findViewById(R.id.textview);
mArrow = (ImageView) headerView.findViewById(R.id.iv_refresh_center);
addView(headerView, params);
}
@Override
public void onInitialized(RefreshKernel kernel, int height, int extendHeight) { // 尺寸定义完成
}
@Override
public void onPullingDown(float percent, int offset, int headHeight, int extendHeight) { // 手指拖动下拉(会连续多次调用)
if (mCircleProgressView == null) return;
float startPercent = 0.20f;
if (percent > startPercent && percent < 1) {
float tempPercent = (percent-startPercent) * 1.0f / (1 - startPercent);
mCircleProgressView.setProgressPersent(tempPercent);
}
}
@Override
public void onReleasing(float percent, int offset, int headHeight, int extendHeight) { // 手指释放之后的持续动画
}
@Override
public void onStartAnimator(RefreshLayout layout, int headHeight, int extendHeight) {
RotateAnimation ta = new RotateAnimation(0, 360,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
ta.setDuration(500);
ta.setRepeatCount(10000);
ta.setInterpolator(new LinearInterpolator());
ta.setFillAfter(true);
mCircleProgressView.startAnimation(ta);
}
@Override
public int onFinish(RefreshLayout layout, boolean success) {
mCircleProgressView.clearAnimation();
return 100; // 动画结束,延迟多少毫秒之后再收回
}
@Override
public void setPrimaryColors(int... colors) {
setBackgroundColor(getResources().getColor(R.color.activity_bg));
}
@NonNull
public View getView() {
return this;
}
@Override
public SpinnerStyle getSpinnerStyle() {
return SpinnerStyle.Translate;
}
@Override
public void onStateChanged(RefreshLayout refreshLayout, RefreshState oldState, RefreshState newState) { // 状态改变事件
switch (newState) {
case None: // 无状态
if (mCircleProgressView != null) mCircleProgressView.setProgressPersent(0);
if (isArrowDown) {
arrowAnimation();
isArrowDown = false;
}
break;
case PullDownToRefresh: // 可以下拉状态
mTextView.setText("下拉即可刷新");
break;
case Refreshing: // 刷新中状态
mTextView.setText("正在刷新数据...");
break;
case ReleaseToRefresh: // 释放就开始刷新状态
mTextView.setText("松开立即刷新");
if (!isArrowDown) {
arrowAnimation();
isArrowDown = true;
}
break;
}
}
private void arrowAnimation() {
RotateAnimation ra = new RotateAnimation(0, isArrowDown ? 0 : 180.0f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
RotateAnimation.RELATIVE_TO_SELF, 0.5f);
ra.setDuration(200);
ra.setRepeatCount(0);
ra.setInterpolator(new LinearInterpolator());
ra.setFillAfter(true);
mArrow.startAnimation(ra);
}
/**
* dp转px
*/
private int dp2px(Context context, float dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, context.getResources().getDisplayMetrics());
}
}
创建一个贝塞尔画圆工具CircleProgressView来画圆弧:
public class CircleProgressView extends View {
private RectF mRectF;
private Paint mPaint;
private int width;
private int height;
private float persent = 0.0f; // 进度
private float lineWidth = 2; // 线宽
public CircleProgressView(Context context) {
super(context);
lineWidth = dp2px(context, 1.0f);
initView();
}
public CircleProgressView(Context context, AttributeSet attrs) {
super(context, attrs);
lineWidth = dp2px(context, 1.0f);
initView();
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = MeasureSpec.getSize(widthMeasureSpec);
height = MeasureSpec.getSize(heightMeasureSpec);
if (width != height) {
int min = Math.min(width, height);
width = min;
height = min;
}
mRectF.left = lineWidth / 2;
mRectF.top = lineWidth / 2;
mRectF.right = width - lineWidth / 2;
mRectF.bottom = height - lineWidth / 2;
}
private void initView() {
mRectF = new RectF();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(getResources().getColor(R.color.theme_color_80));
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(lineWidth);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.TRANSPARENT);
canvas.drawArc(mRectF, 90, persent * 350, false, mPaint);
}
public void setProgressPersent(float persent) {
this.persent = persent;
this.invalidate();
}
// dp转px
private int dp2px(Context context, float dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, context.getResources().getDisplayMetrics());
}
}
在res\layout\创建一个my_refresh_header.xml文件:
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dp"
>
android:id="@+id/iv_head"
android:layout_width="135dp"
android:layout_height="15dp"
android:layout_centerHorizontal="true"
android:src="@mipmap/refresh_head"
/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="12dp"
android:layout_below="@+id/iv_head"
>
android:id="@+id/rlCircleContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
android:id="@+id/circleProgressView"
android:layout_width="22dp"
android:layout_height="22dp"
android:layout_centerInParent="true"
/>
android:id="@+id/iv_refresh_center"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_centerInParent="true"
android:scaleType="fitCenter"
android:src="@mipmap/arrow_up"
/>
android:id="@+id/textview"
style="@style/text_24_80"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@+id/rlCircleContainer"
android:paddingLeft="10dp"
android:text="下拉即可刷新"
/>
使用示例:
public class MainActivity extends AppCompatActivity {
private MyRefreshLayout refreshLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
refreshLayout = (MyRefreshLayout)findViewById(R.id.refreshLayout);
refreshLayout.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh(RefreshLayout refreshlayout) {
refreshlayout.finishRefresh(3000); // 模拟请求数据, 3秒后结束
}
});
refreshLayout.setOnLoadmoreListener(new OnLoadmoreListener() {
@Override
public void onLoadmore(RefreshLayout refreshlayout) {
refreshlayout.finishLoadmore(3000);
}
});
}
}
xml:
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/refreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/activity_bg"
>
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never"
android:background="#236678"
/>