首页设备列表,上拉加载,下拉刷新
This commit is contained in:
@@ -32,6 +32,10 @@ public class CustomRefreshHeader extends RelativeLayout implements RefreshHeader
|
|||||||
|
|
||||||
private ImageView ivRefresh;
|
private ImageView ivRefresh;
|
||||||
private ObjectAnimator rotateAnimator;
|
private ObjectAnimator rotateAnimator;
|
||||||
|
// 用于 onMoving 中的动态效果
|
||||||
|
private float mLastPercent = 0f;
|
||||||
|
// 记录当前缩放值,避免重复设置
|
||||||
|
private float mCurrentScale = 1f;
|
||||||
|
|
||||||
public CustomRefreshHeader(Context context) {
|
public CustomRefreshHeader(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
@@ -47,11 +51,14 @@ public class CustomRefreshHeader extends RelativeLayout implements RefreshHeader
|
|||||||
LayoutInflater.from(context).inflate(R.layout.view_refresh_header, this);
|
LayoutInflater.from(context).inflate(R.layout.view_refresh_header, this);
|
||||||
ivRefresh = findViewById(R.id.ivRefresh);
|
ivRefresh = findViewById(R.id.ivRefresh);
|
||||||
|
|
||||||
|
// 开启硬件加速,提升动画性能
|
||||||
|
setLayerType(LAYER_TYPE_HARDWARE, null);
|
||||||
|
|
||||||
// 初始化 ObjectAnimator
|
// 初始化 ObjectAnimator
|
||||||
rotateAnimator = ObjectAnimator.ofFloat(ivRefresh, "rotation", 0f, 360f);
|
rotateAnimator = ObjectAnimator.ofFloat(ivRefresh, "rotation", 0f, 360f);
|
||||||
rotateAnimator.setDuration(1500);
|
rotateAnimator.setDuration(1500);
|
||||||
rotateAnimator.setRepeatCount(ValueAnimator.INFINITE);
|
rotateAnimator.setRepeatCount(ValueAnimator.INFINITE);
|
||||||
rotateAnimator.setInterpolator(new LinearInterpolator()); // 匀速旋转
|
rotateAnimator.setInterpolator(new LinearInterpolator());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -72,16 +79,36 @@ public class CustomRefreshHeader extends RelativeLayout implements RefreshHeader
|
|||||||
@Override
|
@Override
|
||||||
public int onFinish(@NonNull RefreshLayout layout, boolean success) {
|
public int onFinish(@NonNull RefreshLayout layout, boolean success) {
|
||||||
if (rotateAnimator != null && rotateAnimator.isRunning()) {
|
if (rotateAnimator != null && rotateAnimator.isRunning()) {
|
||||||
// 为了平滑停止,先设置减速插值器,再 cancel 动画
|
|
||||||
rotateAnimator.setInterpolator(new DecelerateInterpolator());
|
rotateAnimator.setInterpolator(new DecelerateInterpolator());
|
||||||
postDelayed(() -> {
|
postDelayed(() -> {
|
||||||
if (rotateAnimator != null) {
|
if (rotateAnimator != null) {
|
||||||
rotateAnimator.cancel();
|
rotateAnimator.cancel();
|
||||||
rotateAnimator.setInterpolator(new LinearInterpolator()); // 恢复为匀速
|
rotateAnimator.setInterpolator(new LinearInterpolator());
|
||||||
}
|
}
|
||||||
}, 300); // 给一点缓冲时间
|
}, 300);
|
||||||
}
|
}
|
||||||
return 500; // 动画停止后延迟 500ms 收起 Header
|
// 动画过渡回正常大小
|
||||||
|
animateToNormalScale();
|
||||||
|
return 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 平滑动画过渡回正常大小
|
||||||
|
*/
|
||||||
|
private void animateToNormalScale() {
|
||||||
|
if (ivRefresh == null) return;
|
||||||
|
|
||||||
|
float startScale = mCurrentScale;
|
||||||
|
ValueAnimator scaleAnimator = ValueAnimator.ofFloat(startScale, 1f);
|
||||||
|
scaleAnimator.setDuration(300);
|
||||||
|
scaleAnimator.setInterpolator(new DecelerateInterpolator());
|
||||||
|
scaleAnimator.addUpdateListener(animation -> {
|
||||||
|
float value = (float) animation.getAnimatedValue();
|
||||||
|
ivRefresh.setScaleX(value);
|
||||||
|
ivRefresh.setScaleY(value);
|
||||||
|
mCurrentScale = value;
|
||||||
|
});
|
||||||
|
scaleAnimator.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- 必须实现的方法 ---
|
// --- 必须实现的方法 ---
|
||||||
@@ -107,7 +134,24 @@ public class CustomRefreshHeader extends RelativeLayout implements RefreshHeader
|
|||||||
|
|
||||||
@SuppressLint("RestrictedApi")
|
@SuppressLint("RestrictedApi")
|
||||||
@Override
|
@Override
|
||||||
public void onMoving(boolean isDragging, float percent, int offset, int height, int maxDragHeight) {}
|
public void onMoving(boolean isDragging, float percent, int offset, int height, int maxDragHeight) {
|
||||||
|
// 只在拖动过程中处理,避免过度计算
|
||||||
|
if (percent != mLastPercent) {
|
||||||
|
mLastPercent = percent;
|
||||||
|
|
||||||
|
// 1. 动态缩放效果:从 0.5 放大到 1.2
|
||||||
|
// 使用 clamp 限制范围:percent 0~1 -> scale 0.5~1.2
|
||||||
|
float targetScale = 0.5f + (0.7f * Math.min(percent, 1.0f));
|
||||||
|
if (Math.abs(targetScale - mCurrentScale) > 0.01f) {
|
||||||
|
mCurrentScale = targetScale;
|
||||||
|
ivRefresh.setScaleX(targetScale);
|
||||||
|
ivRefresh.setScaleY(targetScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 透明度渐变效果(可选)
|
||||||
|
// ivRefresh.setAlpha(Math.min(percent * 1.5f, 1.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("RestrictedApi")
|
@SuppressLint("RestrictedApi")
|
||||||
@Override
|
@Override
|
||||||
@@ -125,6 +169,10 @@ public class CustomRefreshHeader extends RelativeLayout implements RefreshHeader
|
|||||||
@SuppressLint("RestrictedApi")
|
@SuppressLint("RestrictedApi")
|
||||||
@Override
|
@Override
|
||||||
public void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState) {
|
public void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState) {
|
||||||
|
// 状态切换时平滑恢复
|
||||||
|
if (newState == RefreshState.PullDownCanceled) {
|
||||||
|
// 用户取消下拉,恢复到初始状态
|
||||||
|
animateToNormalScale();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user