用当前最流行的下拉刷新pullrefresh框架实现类似QQ的下拉刷新功能

本文介绍了如何使用Android-PullToRefresh框架实现具有刷新成功提示的下拉刷新功能,详细解释了框架的工作原理,包括状态管理、动画控制以及自定义下拉头等内容。通过增加新的状态和修改接口,实现了类似QQ的刷新提示效果,包括状态枚举、方法修改、下拉头基类的扩展以及最终的刷新完成逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用当前最流行的下拉刷新pullrefresh框架实现类似QQ的下拉刷新功能,下载地址为:https://github.com/chrisbanes/Android-PullToRefresh

 

我先解释一下下拉刷新涉及的过程:

1、  肯定要有一个下拉头(下拉脚),在这个源码里面LoadingLayout作为下拉头的基类,你可以参照它已经实现的几个样式自定义自己的下拉头,就是对里面显示的内容,动画进行相应的修改。

2、  下拉的过程涉及几个状态,reset,pulltorefresh,refreshing,releasetorefresh等,对应的每个状态分别有不同的动作,源码里面用IPullRefresh接口把相应的动作进行了声明,我们只需要实现它就可以实现相应的动作。

3、  下拉的过程还涉及到下拉头内容的变化,源码中用ILoadingLayout接口对不同状态下的下拉头内容进行了封装。

4、  源码中最重要的基类是PullToRefreshBase,该类封装了下拉刷新的整个过程的功能,但是该类是个抽象类,里面有两个抽象方法分别为isReadyForPullEnd(),isReadyForPullStart();,这两个方法主要是让你根据自己情况进行下拉和上拉的判断。该类也是一个泛型类,可以根据你传入的视图类型生成对应的刷新视图。

5、  源码中PullToRefreshAdapterViewBase类对PullToRefreshBase类进行了封装,故名思议,主要是对AdapterView类型的刷新视图进行的包装,让像ListView,GridView等继承它实现起来更方便。

 

好了,回到主题,我发现该下拉刷新框架跟QQ的还是有所不一样的,QQ的每次刷新成功都会在下拉头进行提示,而这个刷新完直接回到了初始状态,并没有给出任何提示。

我的实现方法是:

1、在PullToRefreshBase类的内部枚举类State中加了一个刷新成功的状态,

public static enum State {

       /**

        *When the UI is in a state which means that user is not interacting

        *with the Pull-to-Refresh function.

        */

       RESET(0x0),

 

       /**

        *When the UI is being pulled by the user, but has not been pulled far

        *enough so that it refreshes when released.

        */

       PULL_TO_REFRESH(0x1),

 

       /**

        *When the UI is being pulled by the user, and <strong>has</strong>

        *been pulled far enough so that it will refresh when released.

        */

       RELEASE_TO_REFRESH(0x2),

 

       REFRESHING_SUCCEED(0x4),//此处是我加的状态,命名可以随意

       /**

        *When the UI is currently refreshing, caused by a pull gesture.

        */

       REFRESHING(0x8),

 

 

       /**

        *When the UI is currently refreshing, caused by a call to

        * {@link PullToRefreshBase#setRefreshing() setRefreshing()}.

        */

       MANUAL_REFRESHING(0x9),

 

       /**

        *When the UI is currently overscrolling, caused by a fling on the

        * RefreshableView.

        */

       OVERSCROLLING(0x10);

 

       /**

        *Maps an int to a specific state. This is needed when saving state.

        *

        * @param stateInt

        *           - int to map a State to

        * @return State thatstateInt maps to

        */

       static State mapIntToValue(final int stateInt) {

           for (State value : State.values()) {

              if (stateInt == value.getIntValue()) {

                  return value;

              }

           }

 

           // If not, returndefault

           return RESET;

       }

 

       private int mIntValue;

 

       State(int intValue) {

           mIntValue = intValue;

       }

 

       int getIntValue() {

           return mIntValue;

       }

    }

 

2、  既然有刷新成功这个状态,肯定要有相关的操作,这里我对ILoadingLayout,以及IPullRefresh进行了修改。

ILoadingLayout: 我添加了一个方法是对刷新成功内容标签进行设置,

    public voidsetRefreshingCompleteLable(CharSequence completeLable);

IPullRefresh:我对之前的刷新完成方法进行了修改,通过调用者传入一个变量判断是否刷新成功。

原来的方法:public void onRefreshComplete();

现在的方法:public void setRefreshComplete(booleanisSucceed);

 

3、  通过修改2之后我们发现很多地方报错,对的,我们这时只需要对报错的地方进行相应的修改即可,这里我们就要对下拉头基类LoadingLayout进行相应的修改了。

(1)      添加了属性刷新成功的字符,以及获取它的资源值

private CharSequence mCompleteLable;

在构造方法中添加如下行,字符串资源值定义为刷新成功

(2)      在该类我添加了如下方法:

   public final void refreshSucceed(){

      if (null != mHeaderText) {

         mHeaderText.setText(mCompleteLable);

      }

     

      refreshSucceedImpl();

   }

其中这个refreshSucceedImpl为添加的抽象方法,用在具体下拉头中实现。


(3)  分别找到这三个类,在里面实现如下方法,主要用于对刷新成功下来头的显示。

   protected void refreshSucceedImpl() {

            mHeaderImage.clearAnimation();

            mHeaderImage.setVisibility(View.INVISIBLE);

            mHeaderProgress.setVisibility(View.GONE);

       }

4、  最后我们再来对PullToRefreshBase这个类进行最终的修改,就可以大功告成了。

在这个类中找到onfreshComplete()这个方法,我们改成这样

@Override

public final void setRefreshComplete(booleanisSucceed) {

           if (isRefreshing()) {

                    if (isSucceed) {

                             setState(State.REFRESHING_SUCCEED);

                    } else {

                             setState(State.RESET);

                    }

           }

}

如果是刷新成功则,显示刷新成功,如果是刷新失败,我们直接回到初始状态。

回到setState()方法,我们添加相应的改变


然后我们再去实现onRreshComplete()方法

protected void onRefreshComplete() {

           if(mShowViewWhileRefreshing){

                    switch (mCurrentMode) {

                    case PULL_FROM_END:

                             mFooterLayout.refreshSucceed();

                             break;

                    case PULL_FROM_START:

                             mHeaderLayout.refreshSucceed();

                             break;

                    default:

                             // NO-OP

                             break;

                    }

           }

           postDelayed(new Runnable() {

                   

                    @Override

                    public void run() {

                             setState(State.RESET);

                    }

           },500);

}

这里注意一下,postDelayed主要用于显示刷新成功之后回到初始状态,时间设为显示时间,这里我设的是500;

本来以为大工告成,测试的时候发现了一个问题,每次刷新成功显示完后,下拉头的内容先回到初始状态再滑到初始位置,这显然不是我们想看到的,于是我对onreset方法进行了修改:

   /**

    * Called when the UI has been to be updated tobe in the

    * {@linkState#RESET} state.

    */

   protected void onReset() {

      mIsBeingDragged = false;

      mLayoutVisibilityChangesEnabled= true;

      //之前是这样的:

      /**smoothScrollTo(0);

        *mHeaderLayout.reset();

         *  mFooterLayout.reset();*/

       //现在是这样的,在滑动完成之后我们再对下拉内容进行初始化,这样就看不到默认状态了

      smoothScrollTo(0,newOnSmoothScrollFinishedListener() {

        

         @Override

         public voidonSmoothScrollFinished() {

            mHeaderLayout.reset();

            mFooterLayout.reset();

         }

      });

 

      // Always reset both layouts, just in case...

 

}

 

5、  我们在刷新完成的逻辑中调用setRefreshComplete(booleanisSucceed)这个方法即可,根据刷新的结果进行传值,结果如下:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值