小工具知识网

当前位置: 首页 > 行业知识 > Android下拉刷新完全解析,教你如何一分钟实现下拉刷新功能

行业知识

Android下拉刷新完全解析,教你如何一分钟实现下拉刷新功能

2026-11-02 14:26:57 来源:互联网转载

android:layout_weight=“1”

android:gravity=“center_horizontal|top”

android:text=“@string/updated_at” />

在这个布局中,我们包含了一个下拉指示箭头,一个下拉状态文字提示,和一个上次更新的时间。当然,还有一个隐藏的旋转进度条,只有正在刷新的时候我们才会将它显示出来。

布局中所有引用的字符串我们都放在 strings.xml 中,如下所示:

PullToRefreshTest

下拉可以刷新

释放立即刷新

正在刷新…

暂未更新过

上次更新于%1$s前

刚刚更新

时间有问题

二

然后新建一个 RefreshableView 继承自 LinearLayout,代码如下所示:

public class RefreshableView extends LinearLayout implements OnTouchListener {

/**

  • 下拉状态

    */

    public static final int STATUS_PULL_TO_REFRESH = 0;

    /**

    • 释放立即刷新状态

      */

      public static final int STATUS_RELEASE_TO_REFRESH = 1;

      /**

      • 正在刷新状态

        */

        public static final int STATUS_REFRESHING = 2;

        /**

        • 刷新完成或未刷新状态

          */

          public static final int STATUS_REFRESH_FINISHED = 3;

          /**

          • 下拉头部回滚的速度

            */

            public static final int SCROLL_SPEED = -20;

            /**

            • 一分钟的毫秒值,用于判断上次的更新时间

              */

              public static final long ONE_MINUTE = 60 * 1000;

              /**

              • 一小时的毫秒值,用于判断上次的更新时间

                */

                public static final long ONE_HOUR = 60 * ONE_MINUTE;

                /**

                • 一天的毫秒值,用于判断上次的更新时间

                  */

                  public static final long ONE_DAY = 24 * ONE_HOUR;

                  /**

                  • 一月的毫秒值,用于判断上次的更新时间

                    */

                    public static final long ONE_MONTH = 30 * ONE_DAY;

                    /**

                    • 一年的毫秒值,用于判断上次的更新时间

                      */

                      public static final long ONE_YEAR = 12 * ONE_MONTH;

                      /**

                      • 上次更新时间的字符串常量,用于作为SharedPreferences的键值

                        */

                        private static final String UPDATED_AT = “updated_at”;

                        /**

                        • 下拉刷新的回调接口

                          */

                          private PullToRefreshListener mListener;

                          /**

                          • 用于存储上次更新时间

                            */

                            private SharedPreferences preferences;

                            /**

                            • 下拉头的View

                              */

                              private View header;

                              /**

                              • 需要去下拉刷新的ListView

                                */

                                private ListView listView;

                                /**

                                • 刷新时显示的进度条

                                  */

                                  private ProgressBar progressBar;

                                  /**

                                  • 指示下拉和释放的箭头

                                    */

                                    private ImageView arrow;

                                    /**

                                    • 指示下拉和释放的文字描述

                                      */

                                      private TextView description;

                                      /**

                                      • 上次更新时间的文字描述

                                        */

                                        private TextView updateAt;

                                        /**

                                        • 下拉头的布局参数

                                          */

                                          private MarginLayoutParams headerLayoutParams;

                                          /**

                                          • 上次更新时间的毫秒值

                                            */

                                            private long lastUpdateTime;

                                            /**

                                            • 为了防止不同界面的下拉刷新在上次更新时间上互相有冲突,使用id来做区分

                                              */

                                              private int mId = -1;

                                              /**

                                              • 下拉头的高度

                                                */

                                                private int hideHeaderHeight;

                                                /**

                                                • 当前处理什么状态,可选值有STATUS_PULL_TO_REFRESH, STATUS_RELEASE_TO_REFRESH,
                                                • STATUS_REFRESHING 和 STATUS_REFRESH_FINISHED

                                                  */

                                                  private int currentStatus = STATUS_REFRESH_FINISHED;;

                                                  /**

                                                  • 记录上一次的状态是什么,避免进行重复操作

                                                    */

                                                    private int lastStatus = currentStatus;

                                                    /**

                                                    • 手指按下时的屏幕纵坐标

                                                      */

                                                      private float yDown;

                                                      /**

                                                      • 在被判定为滚动之前用户手指可以移动的最大值。

                                                        */

                                                        private int touchSlop;

                                                        /**

                                                        • 是否已加载过一次layout,这里onLayout中的初始化只需加载一次

                                                          */

                                                          private boolean loadOnce;

                                                          /**

                                                          • 当前是否可以下拉,只有ListView滚动到头的时候才允许下拉

                                                            */

                                                            private boolean ableToPull;

                                                            /**

                                                            • 下拉刷新控件的构造函数,会在运行时动态添加一个下拉头的布局。
                                                            • @param context
                                                            • @param attrs

                                                              */

                                                              public RefreshableView(Context context, AttributeSet attrs) {

                                                              super(context, attrs);

                                                              preferences = PreferenceManager.getDefaultSharedPreferences(context);

                                                              header = LayoutInflater.from(context).inflate(R.layout.pull_to_refresh, null, true);

                                                              progressBar = (ProgressBar) header.findViewById(R.id.progress_bar);

                                                              arrow = (ImageView) header.findViewById(R.id.arrow);

                                                              description = (TextView) header.findViewById(R.id.description);

                                                              updateAt = (TextView) header.findViewById(R.id.updated_at);

                                                              touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();

                                                              refreshUpdatedAtValue();

                                                              setOrientation(VERTICAL);

                                                              addView(header, 0);

                                                              }

                                                              /**

                                                              • 进行一些关键性的初始化操作,比如:将下拉头向上偏移进行隐藏,给ListView注册touch事件。

                                                                */

                                                                @Override

                                                                protected void onLayout(boolean changed, int l, int t, int r, int b) {

                                                                super.onLayout(changed, l, t, r, b);

                                                                if (changed && !loadOnce) {

                                                                hideHeaderHeight = -header.getHeight();

                                                                headerLayoutParams = (MarginLayoutParams) header.getLayoutParams();

                                                                headerLayoutParams.topMargin = hideHeaderHeight;

                                                                listView = (ListView) getChildAt(1);

                                                                listView.setOnTouchListener(this);

                                                                loadOnce = true;

                                                                }

                                                                }

                                                                /**

                                                                • 当ListView被触摸时调用,其中处理了各种下拉刷新的具体逻辑。

                                                                  */

                                                                  @Override

                                                                  public boolean onTouch(View v, MotionEvent event) {

                                                                  setIsAbleToPull(event);

                                                                  if (ableToPull) {

                                                                  switch (event.getAction()) {

                                                                  case MotionEvent.ACTION_DOWN:

                                                                  yDown = event.getRawY();

                                                                  break;

                                                                  case MotionEvent.ACTION_MOVE:

                                                                  float yMove = event.getRawY();

                                                                  int distance = (int) (yMove - yDown);

                                                                  // 如果手指是下滑状态,并且下拉头是完全隐藏的,就屏蔽下拉事件

                                                                  if (distance Android IOC架构设计免费获取。

                                                                  群内还有免费的高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术资料,并且还有技术大牛一起讨论交流解决问题。

                                                                  到这里也结束了,在文章最后放上一个小小的福利,以下为小编自己在学习过程中整理出的一个学习思路及方向,从事互联网开发,最主要的是要学好技术,而学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯,更加需要准确的学习方向达到有效的学习效果。

                                                                  由于内容较多就只放上一个大概的大纲,需要更及详细的学习思维导图的点击这里>Android IOC架构设计免费获取。

                                                                  群内还有免费的高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术资料,并且还有技术大牛一起讨论交流解决问题。**

上一篇:vue中将某个不太规则的json转成对象,或者将对象转成json字符串

下一篇:本地服务器url怎么查看?