直接使用 效果图就不上了
自己拿去使用 看看效果
第一步(依赖):
compile 'in.srain.cube:ptr-load-more:1.0.6'
第二步(工具类):
package com.jiaoyu.utils;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import in.srain.cube.views.ptr.PtrClassicFrameLayout;
/**
* Created by DaWei 2018/6/20.
*/
public class PtrClassicRefreshLayout extends PtrClassicFrameLayout {
private boolean disallowInterceptTouchEvent = false;
public PtrClassicRefreshLayout(Context context) {
super(context);
}
public PtrClassicRefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public PtrClassicRefreshLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
disallowInterceptTouchEvent = disallowIntercept;
super.requestDisallowInterceptTouchEvent(disallowIntercept);
}
@Override
public boolean dispatchTouchEvent(MotionEvent e) {
switch (e.getAction()) {
case MotionEvent.ACTION_UP:
this.requestDisallowInterceptTouchEvent(false);
break;
}
if (disallowInterceptTouchEvent) {
return dispatchTouchEventSupper(e);
}
return super.dispatchTouchEvent(e);
}
}
下拉:
package com.jiaoyu.utils;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.FrameLayout;
import android.widget.TextView;
import com.jiaoyu.jinyingjie.R;
import java.text.SimpleDateFormat;
import java.util.Date;
import in.srain.cube.views.ptr.PtrFrameLayout;
import in.srain.cube.views.ptr.PtrUIHandler;
import in.srain.cube.views.ptr.indicator.PtrIndicator;
public class PtrClassicListHeader extends FrameLayout implements PtrUIHandler {
private final static String KEY_Shared = "last_update";
private static SimpleDateFormat sDataFormat = new SimpleDateFormat("MM/dd HH:mm");
private int mRotateAniTime = 50;
protected RotateAnimation mFlipAnimation;
protected RotateAnimation mReverseFlipAnimation;
protected TextView mTitleTextView;
private View mRotateView;
private View mProgressBar;
private long mLastUpdateTime = -1;
private TextView mLastUpdateTextView;
private String mLastUpdateTimeKey;
private boolean mShouldShowLastUpdate;
private LastUpdateTimeUpdater mLastUpdateTimeUpdater = new LastUpdateTimeUpdater();
public PtrClassicListHeader(Context context) {
super(context);
initViews(null);
}
public PtrClassicListHeader(Context context, AttributeSet attrs) {
super(context, attrs);
initViews(attrs);
}
public PtrClassicListHeader(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initViews(attrs);
}
protected void initViews(AttributeSet attrs) {
TypedArray arr = getContext().obtainStyledAttributes(attrs, R.styleable.PtrClassicHeader, 0, 0);
if (arr != null) {
mRotateAniTime = arr.getInt(R.styleable.PtrClassicHeader_ptr_rotate_ani_time, mRotateAniTime);
}
buildAnimation();
View header = LayoutInflater.from(getContext()).inflate(R.layout.pull_to_refresh_footer_list, this);
mRotateView = header.findViewById(R.id.ptr_classic_header_rotate_view);
mTitleTextView = (TextView) header.findViewById(R.id.ptr_classic_header_rotate_view_header_title);
mLastUpdateTextView = (TextView) header.findViewById(R.id.ptr_classic_header_rotate_view_header_last_update);
mProgressBar = header.findViewById(R.id.ptr_classic_header_rotate_view_progressbar);
resetView();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mLastUpdateTimeUpdater != null) {
mLastUpdateTimeUpdater.stop();
}
}
public void setRotateAniTime(int time) {
if (time == mRotateAniTime || time == 0) {
return;
}
mRotateAniTime = time;
buildAnimation();
}
/**
* Specify the last update time by this key string
*
* @param key
*/
public void setLastUpdateTimeKey(String key) {
if (TextUtils.isEmpty(key)) {
return;
}
mLastUpdateTimeKey = key;
}
/**
* Using an object to specify the last update time.
*
* @param object
*/
public void setLastUpdateTimeRelateObject(Object object) {
setLastUpdateTimeKey(object.getClass().getName() + "header");
}
/**
* Using an object to specify the last update time.
*
* @param object
*/
public void setLastUpdateTimeRelateObject(Object object, int postion) {
setLastUpdateTimeKey(object.getClass().getName() + postion + "_header");
}
protected void buildAnimation() {
mFlipAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
mFlipAnimation.setInterpolator(new LinearInterpolator());
mFlipAnimation.setDuration(mRotateAniTime);
mFlipAnimation.setFillAfter(true);
mReverseFlipAnimation = new RotateAnimation(-180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
mReverseFlipAnimation.setInterpolator(new LinearInterpolator());
mReverseFlipAnimation.setDuration(mRotateAniTime);
mReverseFlipAnimation.setFillAfter(true);
}
private void resetView() {
hideRotateView();
mProgressBar.setVisibility(INVISIBLE);
}
private void hideRotateView() {
mRotateView.clearAnimation();
mRotateView.setVisibility(INVISIBLE);
}
@Override
public void onUIReset(PtrFrameLayout frame) {
resetView();
mShouldShowLastUpdate = true;
tryUpdateLastUpdateTime();
}
@Override
public void onUIRefreshPrepare(PtrFrameLayout frame) {
mShouldShowLastUpdate = true;
tryUpdateLastUpdateTime();
mLastUpdateTimeUpdater.start();
mProgressBar.setVisibility(INVISIBLE);
mRotateView.setVisibility(VISIBLE);
mTitleTextView.setVisibility(VISIBLE);
mTitleTextView.setText("下拉刷新");
}
@Override
public void onUIRefreshBegin(PtrFrameLayout frame) {
hideRotateView();
mProgressBar.setVisibility(VISIBLE);
mTitleTextView.setVisibility(VISIBLE);
mTitleTextView.setText("正在刷新...");
tryUpdateLastUpdateTime();
mLastUpdateTimeUpdater.stop();
}
@Override
public void onUIRefreshComplete(PtrFrameLayout frame, boolean isHeader) {
hideRotateView();
mProgressBar.setVisibility(INVISIBLE);
mTitleTextView.setVisibility(VISIBLE);
mTitleTextView.setText("刷新完成");
// update last update time
SharedPreferences sharedPreferences = getContext().getSharedPreferences(KEY_Shared, 0);
if (!TextUtils.isEmpty(mLastUpdateTimeKey)) {
mLastUpdateTime = new Date().getTime();
sharedPreferences.edit().putLong(mLastUpdateTimeKey, mLastUpdateTime).commit();
}
}
private void tryUpdateLastUpdateTime() {
if (TextUtils.isEmpty(mLastUpdateTimeKey) || !mShouldShowLastUpdate) {
mLastUpdateTextView.setVisibility(GONE);
} else {
String time = getLastUpdateTime();
if (TextUtils.isEmpty(time)) {
mLastUpdateTextView.setVisibility(GONE);
} else {
mLastUpdateTextView.setVisibility(VISIBLE);
mLastUpdateTextView.setText(time);
}
}
}
private String getLastUpdateTime() {
if (mLastUpdateTime == -1 && !TextUtils.isEmpty(mLastUpdateTimeKey)) {
mLastUpdateTime = getContext().getSharedPreferences(KEY_Shared, 0).getLong(mLastUpdateTimeKey, -1);
}
if (mLastUpdateTime == -1) {
return null;
}
long diffTime = new Date().getTime() - mLastUpdateTime;
int seconds = (int) (diffTime / 1000);
if (diffTime < 0) {
return null;
}
if (seconds <= 0) {
return null;
}
StringBuilder sb = new StringBuilder();
sb.append("最后刷新:");
Date date = new Date(mLastUpdateTime);
sb.append(sDataFormat.format(date));
return sb.toString();
}
@Override
public void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator) {
final int mOffsetToRefresh = frame.getOffsetToRefresh();
final int currentPos = ptrIndicator.getCurrentPosY();
final int lastPos = ptrIndicator.getLastPosY();
if (currentPos < mOffsetToRefresh && lastPos >= mOffsetToRefresh) {
if (isUnderTouch && status == PtrFrameLayout.PTR_STATUS_PREPARE) {
crossRotateLineFromBottomUnderTouch(frame);
if (mRotateView != null) {
mRotateView.clearAnimation();
mRotateView.startAnimation(mReverseFlipAnimation);
}
}
} else if (currentPos > mOffsetToRefresh && lastPos <= mOffsetToRefresh) {
if (isUnderTouch && status == PtrFrameLayout.PTR_STATUS_PREPARE) {
crossRotateLineFromTopUnderTouch(frame);
if (mRotateView != null) {
mRotateView.clearAnimation();
mRotateView.startAnimation(mFlipAnimation);
}
}
}
}
private void crossRotateLineFromTopUnderTouch(PtrFrameLayout frame) {
if (!frame.isPullToRefresh()) {
mTitleTextView.setVisibility(VISIBLE);
mTitleTextView.setText("释放立即刷新");
}
}
private void crossRotateLineFromBottomUnderTouch(PtrFrameLayout frame) {
mTitleTextView.setVisibility(VISIBLE);
mTitleTextView.setText("下拉刷新");
}
private class LastUpdateTimeUpdater implements Runnable {
private boolean mRunning = false;
private void start() {
if (TextUtils.isEmpty(mLastUpdateTimeKey)) {
return;
}
mRunning = true;
run();
}
private void stop() {
mRunning = false;
removeCallbacks(this);
}
@Override
public void run() {
tryUpdateLastUpdateTime();
if (mRunning) {
postDelayed(this, 1000);
}
}
}
}
上拉:
package com.jiaoyu.utils;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.FrameLayout;
import android.widget.TextView;
import com.jiaoyu.jinyingjie.R;
import java.text.SimpleDateFormat;
import java.util.Date;
import in.srain.cube.views.ptr.PtrFrameLayout;
import in.srain.cube.views.ptr.PtrUIHandler;
import in.srain.cube.views.ptr.indicator.PtrIndicator;
public class PtrClassicListFooter extends FrameLayout implements PtrUIHandler {
private final static String KEY_Shared = "last_update";
private static SimpleDateFormat sDataFormat = new SimpleDateFormat("MM/dd HH:mm");
private int mRotateAniTime = 50;
protected RotateAnimation mFlipAnimation;
protected RotateAnimation mReverseFlipAnimation;
protected TextView mTitleTextView;
private View mRotateView;
private View mProgressBar;
private long mLastUpdateTime = -1;
private TextView mLastUpdateTextView;
private String mLastUpdateTimeKey;
private boolean mShouldShowLastUpdate;
private LastUpdateTimeUpdater mLastUpdateTimeUpdater = new LastUpdateTimeUpdater();
public PtrClassicListFooter(Context context) {
super(context);
initViews(null);
}
public PtrClassicListFooter(Context context, AttributeSet attrs) {
super(context, attrs);
initViews(attrs);
}
public PtrClassicListFooter(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initViews(attrs);
}
protected void initViews(AttributeSet attrs) {
TypedArray arr = getContext().obtainStyledAttributes(attrs, R.styleable.PtrClassicHeader, 0, 0);
if (arr != null) {
mRotateAniTime = arr.getInt(R.styleable.PtrClassicHeader_ptr_rotate_ani_time, mRotateAniTime);
}
buildAnimation();
View header = LayoutInflater.from(getContext()).inflate(R.layout.pull_to_refresh_footer_list, this);
mRotateView = header.findViewById(R.id.ptr_classic_header_rotate_view);
mTitleTextView = (TextView) header.findViewById(R.id.ptr_classic_header_rotate_view_header_title);
mLastUpdateTextView = (TextView) header.findViewById(R.id.ptr_classic_header_rotate_view_header_last_update);
mProgressBar = header.findViewById(R.id.ptr_classic_header_rotate_view_progressbar);
resetView();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mLastUpdateTimeUpdater != null) {
mLastUpdateTimeUpdater.stop();
}
}
public void setRotateAniTime(int time) {
if (time == mRotateAniTime || time == 0) {
return;
}
mRotateAniTime = time;
buildAnimation();
}
/**
* Specify the last update time by this key string
*
* @param key
*/
public void setLastUpdateTimeKey(String key) {
if (TextUtils.isEmpty(key)) {
return;
}
mLastUpdateTimeKey = key;
}
/**
* Using an object to specify the last update time.
*
* @param object
*/
public void setLastUpdateTimeRelateObject(Object object) {
setLastUpdateTimeKey(object.getClass().getName() + "footer");
}
protected void buildAnimation() {
mFlipAnimation = new RotateAnimation(0, -180, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
mFlipAnimation.setInterpolator(new LinearInterpolator());
mFlipAnimation.setDuration(mRotateAniTime);
mFlipAnimation.setFillAfter(true);
mReverseFlipAnimation = new RotateAnimation(-180, 0, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f);
mReverseFlipAnimation.setInterpolator(new LinearInterpolator());
mReverseFlipAnimation.setDuration(mRotateAniTime);
mReverseFlipAnimation.setFillAfter(true);
}
private void resetView() {
hideRotateView();
mProgressBar.setVisibility(INVISIBLE);
}
private void hideRotateView() {
mRotateView.clearAnimation();
mRotateView.setVisibility(INVISIBLE);
}
@Override
public void onUIReset(PtrFrameLayout frame) {
resetView();
mShouldShowLastUpdate = true;
tryUpdateLastUpdateTime();
}
@Override
public void onUIRefreshPrepare(PtrFrameLayout frame) {
mShouldShowLastUpdate = true;
tryUpdateLastUpdateTime();
mLastUpdateTimeUpdater.start();
mProgressBar.setVisibility(INVISIBLE);
mRotateView.setVisibility(VISIBLE);
mTitleTextView.setVisibility(VISIBLE);
mTitleTextView.setText("上拉加载更多");
}
@Override
public void onUIRefreshBegin(PtrFrameLayout frame) {
mShouldShowLastUpdate = false;
hideRotateView();
mProgressBar.setVisibility(VISIBLE);
mTitleTextView.setVisibility(VISIBLE);
mTitleTextView.setText("正在加载...");
tryUpdateLastUpdateTime();
mLastUpdateTimeUpdater.stop();
}
@Override
public void onUIRefreshComplete(PtrFrameLayout frame, boolean isHeader) {
if (isHeader) {
return;
}
hideRotateView();
mProgressBar.setVisibility(INVISIBLE);
mTitleTextView.setVisibility(VISIBLE);
mTitleTextView.setText("加载完成");
// update last update time
SharedPreferences sharedPreferences = getContext().getSharedPreferences(KEY_Shared, 0);
if (!TextUtils.isEmpty(mLastUpdateTimeKey)) {
mLastUpdateTime = new Date().getTime();
sharedPreferences.edit().putLong(mLastUpdateTimeKey, mLastUpdateTime).commit();
}
}
private void tryUpdateLastUpdateTime() {
if (TextUtils.isEmpty(mLastUpdateTimeKey) || !mShouldShowLastUpdate) {
mLastUpdateTextView.setVisibility(GONE);
} else {
String time = getLastUpdateTime();
if (TextUtils.isEmpty(time)) {
mLastUpdateTextView.setVisibility(GONE);
} else {
mLastUpdateTextView.setVisibility(VISIBLE);
mLastUpdateTextView.setText(time);
}
}
}
private String getLastUpdateTime() {
if (mLastUpdateTime == -1 && !TextUtils.isEmpty(mLastUpdateTimeKey)) {
mLastUpdateTime = getContext().getSharedPreferences(KEY_Shared, 0).getLong(mLastUpdateTimeKey, -1);
}
if (mLastUpdateTime == -1) {
return null;
}
long diffTime = new Date().getTime() - mLastUpdateTime;
int seconds = (int) (diffTime / 1000);
if (diffTime < 0) {
return null;
}
if (seconds <= 0) {
return null;
}
StringBuilder sb = new StringBuilder();
sb.append("最后加载:");
Date date = new Date(mLastUpdateTime);
sb.append(sDataFormat.format(date));
return sb.toString();
}
@Override
public void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator) {
final int mOffsetToRefresh = frame.getOffsetToRefresh();
final int currentPos = ptrIndicator.getCurrentPosY();
final int lastPos = ptrIndicator.getLastPosY();
if (currentPos < mOffsetToRefresh && lastPos >= mOffsetToRefresh) {
if (isUnderTouch && status == PtrFrameLayout.PTR_STATUS_PREPARE) {
crossRotateLineFromBottomUnderTouch(frame);
if (mRotateView != null) {
mRotateView.clearAnimation();
mRotateView.startAnimation(mReverseFlipAnimation);
}
}
} else if (currentPos > mOffsetToRefresh && lastPos <= mOffsetToRefresh) {
if (isUnderTouch && status == PtrFrameLayout.PTR_STATUS_PREPARE) {
crossRotateLineFromTopUnderTouch(frame);
if (mRotateView != null) {
mRotateView.clearAnimation();
mRotateView.startAnimation(mFlipAnimation);
}
}
}
}
private void crossRotateLineFromTopUnderTouch(PtrFrameLayout frame) {
if (!frame.isPullToRefresh()) {
mTitleTextView.setVisibility(VISIBLE);
mTitleTextView.setText("释放立即加载");
}
}
private void crossRotateLineFromBottomUnderTouch(PtrFrameLayout frame) {
mTitleTextView.setVisibility(VISIBLE);
mTitleTextView.setText("上拉加载更多");
}
private class LastUpdateTimeUpdater implements Runnable {
private boolean mRunning = false;
private void start() {
if (TextUtils.isEmpty(mLastUpdateTimeKey)) {
return;
}
mRunning = true;
run();
}
private void stop() {
mRunning = false;
removeCallbacks(this);
}
@Override
public void run() {
tryUpdateLastUpdateTime();
if (mRunning) {
postDelayed(this, 1000);
}
}
}
}
直接复制加入工具类。
第三步(布局添加):
<com.jiaoyu.utils.PtrClassicRefreshLayout android:id="@+id/fragment_consultation_ptr" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1">
使用PtrClassicRefreshlayout 包裹你的 Listview recyclerview 就可以了 (记住包名com.)
第四步(使用下拉刷新,上拉加载):
初始化 PtrClassicRefreshlayout
private PtrClassicRefreshLayout fragment_consultation_ptr;
fragment_consultation_ptr = (PtrClassicRefreshLayout)findViewById(R.id.fragment_consultation_ptr);
(根据情况添加下面方法)
// 头部阻尼系数 fragment_consultation_ptr.setResistanceHeader(1.7f); // 底部阻尼系数 fragment_consultation_ptr.setResistanceFooter(1.7f); // 默认1.2f,移动达到头部高度1.2倍时触发刷新操作 fragment_consultation_ptr.setRatioOfHeaderHeightToRefresh(1.2f); // 头部回弹时间 fragment_consultation_ptr.setDurationToCloseHeader(1000); // 底部回弹时间 fragment_consultation_ptr.setDurationToCloseFooter(1000); // 释放刷新 fragment_consultation_ptr.setPullToRefresh(false); // 释放时恢复到刷新状态的时间 fragment_consultation_ptr.setDurationToBackHeader(200); fragment_consultation_ptr.setDurationToBackFooter(200);
// ------------------------------ 刷新方法----------------------------------- // PtrClassicListHeader header = new PtrClassicListHeader(getContext()); header.setLastUpdateTimeRelateObject(this); // PtrClassicListFooter footer = new PtrClassicListFooter(getContext()); footer.setLastUpdateTimeRelateObject(this); // fragment_consultation_ptr.setFooterView(footer); fragment_consultation_ptr.addPtrUIHandler(footer); // fragment_consultation_ptr.setHeaderView(header); fragment_consultation_ptr.addPtrUIHandler(header); fragment_consultation_ptr.setPtrHandler(new PtrDefaultHandler2() { @Override public void onLoadMoreBegin(PtrFrameLayout frame) { //上拉加载 pagenum++; hhClict();// fragment_consultation_ptr.refreshComplete(); } @Override public void onRefreshBegin(PtrFrameLayout frame) { // 下拉刷新 pagenum = 1; entityBeans.clear(); lv.removeHeaderView(viewc); hhClict(); fragment_consultation_ptr.refreshComplete(); } @Override public boolean checkCanDoLoadMore(PtrFrameLayout frame, View content, View footer) { return super.checkCanDoLoadMore(frame, content, footer); } @Override public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) { return super.checkCanDoRefresh(frame, content, header); } }); // ------------------------------------------------------------------
补充下布局:
<?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">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="60dp">
<LinearLayout
android:id="@+id/ptr_classic_header_rotate_view_header_text"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/ptr_classic_header_rotate_view_header_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#666666"
android:textSize="12sp"/>
<TextView
android:id="@+id/ptr_classic_header_rotate_view_header_last_update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:textColor="#999999"
android:textSize="10sp"/>
</LinearLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:layout_toLeftOf="@+id/ptr_classic_header_rotate_view_header_text">
<ImageView
android:id="@+id/ptr_classic_header_rotate_view"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_gravity="center"
/>
<!--android:src="@drawable/theme_blue_pull_to_refresh_up"-->
<ProgressBar
android:id="@+id/ptr_classic_header_rotate_view_progressbar"
android:layout_width="20dip"
android:layout_height="20dip"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:gravity="center"
android:layout_centerVertical="true"
android:layout_marginRight="8dp"
android:visibility="invisible"/>
<!--android:indeterminateDrawable="@anim/pull_to_refresh_update_loading_progressbar_anim"-->
</FrameLayout>
</RelativeLayout>
</LinearLayout>
OK