前言
参考https://github.com/Aspsine/SwipeToLoadLayout,将其中样例代码Twitter风格的代码提取出来。
SwipeToLoadLayout aar包下载地址:https://download.csdn.net/download/chensenli/10766602
先看效果图
主布局文件代码
最外层使用SwipeToLoadLayout进行包裹,在RecycleView的上下添加头部刷新和尾部刷新
<com.aspsine.swipetoloadlayout.SwipeToLoadLayout
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:id="@+id/swipeToLoadLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:swipe_style="classic"
tools:context="com.csl.refreshrecycleview.MainActivity">
<include
android:id="@id/swipe_refresh_header"
layout="@layout/layout_twitter_header" />
<android.support.v7.widget.RecyclerView
android:id="@id/swipe_target"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false" />
<include
android:id="@id/swipe_load_more_footer"
layout="@layout/layout_classic_footer" />
</com.aspsine.swipetoloadlayout.SwipeToLoadLayout>
自定义头布局
<com.csl.refreshrecycleview.TwitterRefreshHeaderView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_gravity="center">
<ImageView
android:id="@+id/ivArrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="48dp"
android:layout_toLeftOf="@+id/tvRefresh"
android:background="@mipmap/twitter_pull_arrow" />
<ImageView
android:id="@+id/ivSuccess"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="48dp"
android:layout_toLeftOf="@+id/tvRefresh"
android:background="@mipmap/qq_refresh_success" />
<ProgressBar
android:id="@+id/progressbar"
style="?android:attr/progressBarStyleSmallInverse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="48dp"
android:layout_toLeftOf="@+id/tvRefresh" />
<TextView
android:id="@+id/tvRefresh"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:textColor="?attr/colorPrimary" />
</RelativeLayout>
</com.csl.refreshrecycleview.TwitterRefreshHeaderView>
public class TwitterRefreshHeaderView extends SwipeRefreshHeaderLayout {
private ImageView ivArrow;
private ImageView ivSuccess;
private TextView tvRefresh;
private ProgressBar progressBar;
private int mHeaderHeight;
private Animation rotateUp;
private Animation rotateDown;
private boolean rotated = false;
public TwitterRefreshHeaderView(Context context) {
this(context, null);
}
public TwitterRefreshHeaderView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TwitterRefreshHeaderView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mHeaderHeight = getResources().getDimensionPixelOffset(R.dimen.refresh_header_height_twitter);
rotateUp = AnimationUtils.loadAnimation(context, R.anim.rotate_up);
rotateDown = AnimationUtils.loadAnimation(context, R.anim.rotate_down);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
tvRefresh = (TextView) findViewById(R.id.tvRefresh);
ivArrow = (ImageView) findViewById(R.id.ivArrow);
ivSuccess = (ImageView) findViewById(R.id.ivSuccess);
progressBar = (ProgressBar) findViewById(R.id.progressbar);
}
@Override
public void onRefresh() {
ivSuccess.setVisibility(GONE);
ivArrow.clearAnimation();
ivArrow.setVisibility(GONE);
progressBar.setVisibility(VISIBLE);
tvRefresh.setText("REFRESHING");
}
@Override
public void onPrepare() {
Log.d("TwitterRefreshHeader", "onPrepare()");
}
@Override
public void onMove(int y, boolean isComplete, boolean automatic) {
if (!isComplete) {
ivArrow.setVisibility(VISIBLE);
progressBar.setVisibility(GONE);
ivSuccess.setVisibility(GONE);
if (y > mHeaderHeight) {
tvRefresh.setText("RELEASE TO REFRESH");
if (!rotated) {
ivArrow.clearAnimation();
ivArrow.startAnimation(rotateUp);
rotated = true;
}
} else if (y < mHeaderHeight) {
if (rotated) {
ivArrow.clearAnimation();
ivArrow.startAnimation(rotateDown);
rotated = false;
}
tvRefresh.setText("SWIPE TO REFRESH");
}
}
}
@Override
public void onRelease() {
Log.d("TwitterRefreshHeader", "onRelease()");
}
@Override
public void onComplete() {
rotated = false;
ivSuccess.setVisibility(VISIBLE);
ivArrow.clearAnimation();
ivArrow.setVisibility(GONE);
progressBar.setVisibility(GONE);
tvRefresh.setText("COMPLETE");
}
@Override
public void onReset() {
rotated = false;
ivSuccess.setVisibility(GONE);
ivArrow.clearAnimation();
ivArrow.setVisibility(GONE);
progressBar.setVisibility(GONE);
}
}
自定义尾布局
<com.csl.refreshrecycleview.ClassicLoadMoreFooterView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="60dp">
<ProgressBar
android:id="@+id/progressbar"
style="?android:attr/progressBarStyleSmallInverse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="8dp"
android:layout_toLeftOf="@+id/tvLoadMore" />
<ImageView
android:id="@+id/ivSuccess"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="8dp"
android:layout_toLeftOf="@+id/tvLoadMore"
android:background="@mipmap/qq_refresh_success" />
<TextView
android:id="@+id/tvLoadMore"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:text="LoadMore"
android:textColor="?attr/colorPrimary" />
</RelativeLayout>
</com.csl.refreshrecycleview.ClassicLoadMoreFooterView>
public class ClassicLoadMoreFooterView extends SwipeLoadMoreFooterLayout {
private TextView tvLoadMore;
private ImageView ivSuccess;
private ProgressBar progressBar;
private int mFooterHeight;
public ClassicLoadMoreFooterView(Context context) {
this(context, null);
}
public ClassicLoadMoreFooterView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ClassicLoadMoreFooterView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mFooterHeight = getResources().getDimensionPixelOffset(R.dimen.load_more_footer_height_classic);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
tvLoadMore = (TextView) findViewById(R.id.tvLoadMore);
ivSuccess = (ImageView) findViewById(R.id.ivSuccess);
progressBar = (ProgressBar) findViewById(R.id.progressbar);
}
@Override
public void onPrepare() {
ivSuccess.setVisibility(GONE);
}
@Override
public void onMove(int y, boolean isComplete, boolean automatic) {
if (!isComplete) {
ivSuccess.setVisibility(GONE);
progressBar.setVisibility(GONE);
if (-y >= mFooterHeight) {
tvLoadMore.setText("RELEASE TO LOAD MORE");
} else {
tvLoadMore.setText("SWIPE TO LOAD MORE");
}
}
}
@Override
public void onLoadMore() {
tvLoadMore.setText("LOADING MORE");
progressBar.setVisibility(VISIBLE);
}
@Override
public void onRelease() {
}
@Override
public void onComplete() {
progressBar.setVisibility(GONE);
ivSuccess.setVisibility(VISIBLE);
}
@Override
public void onReset() {
ivSuccess.setVisibility(GONE);
}
}
RecycleView的展示
打开页面时,默认进行下拉刷新
mLayout.post(new Runnable() {
@Override
public void run() {
mLayout.setRefreshing(true);
}
});
根据RecycleView的状态判断是否开启加载更多
mRv.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if (newState == RecyclerView.SCROLL_STATE_IDLE ){
if (!ViewCompat.canScrollVertically(recyclerView, 1)){
mLayout.setLoadingMore(true);
}
}
}
});
在onRefresh()和onLoadMore()里面写刷新逻辑。此处是模拟数据,实际在此处进行网络请求。
@Override
public void onRefresh() {
for (int i = 0; i < 3; i++) {
list.add(0,"header: "+i);
}
mLayout.setRefreshing(false);
mAdapter.notifyDataSetChanged();
}
@Override
public void onLoadMore() {
for (int i = 0; i < 3; i++) {
list.add("footer: "+i);
}
mLayout.setLoadingMore(false);
mAdapter.notifyDataSetChanged();
}