运行有问题或需要源码请点赞关注收藏后评论区留言~~~
一、正常下拉与下拉刷新的冲突处理
电商App的首页通常都支持下拉刷新,比如京东首页的头部轮播图一直顶到系统的状态栏,并且页面下拉到顶后,继续下拉会拉出带有下拉刷新字样的布局,此时松手会触发页面的刷新动作,虽然Android提供了专门的下拉刷新布局SwipeRefreshLayout,但是它没有实现页面随手势下滚的动态效果,所以只能我们自己编写一个自定义的布局控件。
自定义的下拉刷新布局首先要能够区分是页面的正常下滚还是拉到头部要求刷新,二者之间的区别很简单,直观上就是判断当前页面是否拉到顶,倘若还没拉到顶,继续下拉动作属于正常的页面滚动,倘若已经拉到顶,继续下拉动作才会拉出头部提示刷新,所以此处需要捕捉页面滚动到顶部的事件,相对应的是页面滚动到底部的事件。鉴于App首页基本采用滚动视图实现页面滚动功能
对于下面几种情况要统筹管理
1:水平方向的左右滑动 不做额外处理
2:垂直方向的向上拉动 不做额外处理
3:下拉的时候尚未拉到页面顶部 不做额外处理
4:拉动顶之后继续下拉,则在隐藏工具栏的同时让下拉头部跟着往下滑动
5:下拉刷新过程中松开手势 判断下拉滚动的距离,距离太短则直接缩回头部,不刷新页面,只有距离足够长才会刷新页面,等待刷新完毕再缩回头部
实现效果如下
一直向上拉到顶就会自动刷新
代码如下
Java类
package com.example.event; import android.annotation.SuppressLint; import android.app.ProgressDialog; import android.graphics.Color; import android.os.Bundle; import android.os.Handler; import androidx.appcompat.app.AppCompatActivity; import android.os.Looper; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.TextView; import com.example.event.constant.ImageList; import com.example.event.util.StatusBarUtil; import com.example.event.util.Utils; import com.example.event.widget.BannerPager; import com.example.event.widget.PullDownRefreshLayout; @SuppressLint("DefaultLocale") public class PullRefreshActivity extends AppCompatActivity implements PullDownRefreshLayout.PullRefreshListener { private static final String TAG = "PullRefreshActivity"; private PullDownRefreshLayout pdrl_main; // 声明一个下拉刷新布局对象 private TextView tv_flipper; // 声明一个文本视图对象 private LinearLayout ll_title; // 声明一个线性布局对象 private ImageView iv_scan; // 声明一个图像视图对象 private ImageView iv_msg; // 声明一个图像视图对象 private boolean isDragging = false; // 是否正在拖动 private ProgressDialog mDialog; // 声明一个进度对话框对象 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_pull_refresh); pdrl_main = findViewById(R.id.pdrl_main); pdrl_main.setOnRefreshListener(this); // 设置下拉刷新监听器 tv_flipper = findViewById(R.id.tv_flipper); ll_title = findViewById(R.id.ll_title); iv_scan = findViewById(R.id.iv_scan); iv_msg = findViewById(R.id.iv_msg); BannerPager banner = findViewById(R.id.banner_pager); LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) banner.getLayoutParams(); params.height = (int) (Utils.getScreenWidth(this) * 250f / 640f); banner.setLayoutParams(params); // 设置广告轮播条的布局参数 banner.setImage(ImageList.getDefault()); // 设置广告轮播条的图片列表 // 设置广告轮播条的图片点击监听器 banner.setOnBannerListener(position -> { String desc = String.format("您点击了第%d张图片", position + 1); tv_flipper.setText(desc); }); floatStatusBar(); // 添加悬浮状态栏效果 } private void floatStatusBar() { // 让App页面扩展到状态栏区域 StatusBarUtil.fullScreen(this); RelativeLayout.LayoutParams titleParams = (RelativeLayout.LayoutParams) ll_title.getLayoutParams(); // 标题栏在上方留出一段距离,看起来仍在状态栏下方 titleParams.topMargin = StatusBarUtil.getStatusBarHeight(this); ll_title.setLayoutParams(titleParams); } // 开始页面刷新 private void beginRefresh() { if (mDialog == null || !mDialog.isShowing()) { // 显示进度对话框 mDialog = ProgressDialog.show(this, "请稍等", "正在努力刷新页面"); // 延迟1秒后启动刷新结束任务 new Handler(Looper.myLooper()).postDelayed(() -> endRefresh(), 1000); } } // 结束页面刷新 private void endRefresh() { if (isDragging) { mDialog.dismiss(); // 关闭进度对话框 pdrl_main.finishRefresh(); isDragging = false; } } // 计算标题栏与状态栏的渐变背景色 private int getTitleBgColor(double scale) { int alpha = (int) Math.round(scale / 2 * 255); alpha = Math.min(alpha, 255); return Color.argb(alpha, 255, 255, 255); } // 在下拉刷新时触发 @Override public void pullRefresh() { isDragging = true; beginRefresh(); // 开始页面刷新 } // 在往上拉动时触发 @Override public void pullUp(double scale) { int bgColor = getTitleBgColor(scale); ll_title.setBackgroundColor(bgColor); ll_title.setVisibility(View.VISIBLE); iv_scan.setImageResource(R.drawable.icon_scan_gray); iv_msg.setImageResource(R.drawable.icon_msg_gray); // 上拉页面,让状态栏背景渐渐变为白色 StatusBarUtil.setStatusBarColor(this, bgColor, true); } // 在往下拉动时触发 @Override public void pullDown(double scale) { int bgColor = getTitleBgColor(scale); ll_title.setBackgroundColor(bgColor); ll_title.setVisibility(View.VISIBLE); iv_scan.setImageResource(R.drawable.icon_scan_white); iv_msg.setImageResource(R.drawable.icon_msg_white); // 下拉到顶了,让状态栏背景渐渐变为透明 StatusBarUtil.setStatusBarColor(this, bgColor, false); } @Override public void hideTitle() { ll_title.setVisibility(View.INVISIBLE); } @Override public void showTitle() { ll_title.setVisibility(View.VISIBLE); } }
XML文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/white"> <com.example.event.widget.PullDownRefreshLayout android:id="@+id/pdrl_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.example.event.widget.PullDownScrollView android:id="@+id/pdsv_main" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <com.example.event.widget.BannerPager android:id="@+id/banner_pager" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/tv_flipper" android:layout_width="match_parent" android:layout_height="300dp" android:background="#eeffee" android:gravity="top|center_horizontal" android:paddingTop="10dp" android:text="请反复下拉页面和上拉页面" android:textColor="@color/black" android:textSize="17sp" /> <View android:layout_width="match_parent" android:layout_height="1000dp" android:background="#9999ff" /> <View android:layout_width="match_parent" android:layout_height="10dp" android:background="@color/white" /> </LinearLayout> </com.example.event.widget.PullDownScrollView> </com.example.event.widget.PullDownRefreshLayout> <!-- title_drag.xml是带搜索框的工具栏布局 --> <include layout="@layout/title_drag" /> </RelativeLayout>
创作不易 觉得有帮助请点赞关注收藏~~~