Android App事件交互Event之模仿京东App实现下拉刷新功能(附源码 可直接使用)

简介: Android App事件交互Event之模仿京东App实现下拉刷新功能(附源码 可直接使用)

运行有问题或需要源码请点赞关注收藏后评论区留言~~~

一、正常下拉与下拉刷新的冲突处理

电商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>

创作不易 觉得有帮助请点赞关注收藏~~~

相关文章
|
Ubuntu 开发工具 Android开发
Repo下载AOSP源码:基于ubuntu22.04 环境配置,android-12.0.0_r32
本文介绍了在基于Ubuntu 22.04的环境下配置Python 3.9、安装repo工具、下载和同步AOSP源码包以及处理repo同步错误的详细步骤。
1891 0
Repo下载AOSP源码:基于ubuntu22.04 环境配置,android-12.0.0_r32
|
XML 搜索推荐 Android开发
Android改变进度条控件progressbar的样式(根据源码修改)
本文介绍了如何基于Android源码自定义ProgressBar样式。首先分析了系统源码中ProgressBar样式的定义,发现其依赖一张旋转图片实现动画效果。接着分两步指导开发者实现自定义:1) 模仿源码创建一个旋转动画XML文件(放置在drawable文件夹),修改图片为自定义样式;2) 在UI控件中通过`indeterminateDrawable`属性应用该动画。最终实现简单且个性化的ProgressBar效果,附带效果图展示。
738 2
|
NoSQL 应用服务中间件 PHP
布谷一对一直播源码android版环境配置流程及功能明细
部署需基于 CentOS 7.9 系统,硬盘不低于 40G,使用宝塔面板安装环境,包括 PHP 7.3(含 Redis、Fileinfo 扩展)、Nginx、MySQL 5.6、Redis 和最新 Composer。Swoole 扩展需按步骤配置。2021.08.05 后部署需将站点目录设为 public 并用 ThinkPHP 伪静态。开发环境建议 Windows 操作系统与最新 Android Studio,基础配置涉及 APP 名称修改、接口域名更换、包名调整及第三方登录分享(如 QQ、微信)的配置,同时需完成阿里云与腾讯云相关设置。
|
XML 移动开发 开发者
京东商品详情数据接口(H5、APP 端)
京东商品详情数据接口是为H5和APP开发者提供的工具,支持获取商品名称、价格、库存、销量、评价、图片等详细信息,优化应用功能。接口返回JSON或XML格式数据,方便解析处理。适用于电商导购、社交媒体分享、活动推广、价格监控等场景,提升用户体验和购物决策效率。示例代码展示了使用Python发送GET请求的方法。
|
JSON 数据挖掘 API
京东app商品详情API接口系列(京东 API)
本文介绍了使用 Python 调用京东商品详情 API 的方法。前期需安装 `requests` 库处理 HTTP 请求,导入 `json` 库解析 JSON 数据。接口通过商品 ID 获取详细信息,如价格、图片、评价等。示例代码展示了如何构建请求并处理响应数据。应用场景包括电商开发、市场调研和数据分析等,帮助提升用户体验、优化推荐系统及制定市场策略。
|
开发工具 git 索引
repo sync 更新源码 android-12.0.0_r34, fatal: 不能重置索引文件至版本 ‘v2.27^0‘。
本文描述了在更新AOSP 12源码时遇到的repo同步错误,并提供了通过手动git pull更新repo工具来解决这一问题的方法。
987 1
|
开发工具 uml git
AOSP源码下载方法,解决repo sync错误:android-13.0.0_r82
本文分享了下载AOSP源码的方法,包括如何使用repo工具和处理常见的repo sync错误,以及配置Python环境以确保顺利同步特定版本的AOSP代码。
3723 0
AOSP源码下载方法,解决repo sync错误:android-13.0.0_r82
|
Java Android开发 芯片
使用Android Studio导入Android源码:基于全志H713 AOSP,方便解决编译、编码问题
本文介绍了如何将基于全志H713芯片的AOSP Android源码导入Android Studio以解决编译和编码问题,通过操作步骤的详细说明,展示了在Android Studio中利用代码提示和补全功能快速定位并修复编译错误的方法。
1797 0
使用Android Studio导入Android源码:基于全志H713 AOSP,方便解决编译、编码问题
|
Android开发
我的Android 进阶修炼(1): AOSP源码根目录结构
本文介绍了AOSP源码的根目录结构,提供了基于MTK9269 Android 9.0源码的目录说明,帮助读者了解AOSP源码的组织方式和各目录的功能。
1762 0
我的Android 进阶修炼(1): AOSP源码根目录结构
|
小程序
uni-app开发微信小程序使用onPullDownRefresh(下拉刷新)总结
uni-app开发微信小程序使用onPullDownRefresh(下拉刷新)总结
2840 0

热门文章

最新文章