自定义Listview实现下拉刷新

自定义Listview分析:

 

GetListview/findViewById时调用的(用户第一个调用的方法):

1,首先3个构造方法都是在getlistviewfindViewById()的时候调用的,用于初始化一些关于listview的一些参数。(其实findviewbyid就是new一个标签指定类型的对象,并且把标签中指定的属性作为一个set集合传过去,然后返回该标签类型对象,仅此而已)

2Initcontext)  初始化两个动画,一个inflateer  一个mRefreshView和它内部的四个控件。其次给它的mRrefreshViewheader)绑定了一个点击事件监听器,OnClickRefreshListener

该监听器监听点击动作(动作产生时:调用(如果mRefreshStateRefreshIngPrepareForRefresh()和OnRefresh();其中具体的细节稍后再谈。),还有super.setOnScrollListerner()为该控件绑定滚动监听;

其中还包括了对mRefreshView的测量,测量过程不太懂。。。。

 

用户调用的第二个方法setOnRefreshListener();

1,在用户通过getListview或许findviewById以后紧接着就会给该自定义控件绑定一个OnRefreshListener(当然是自定义的),以便监听刷新事件的触发,开启异步任务。

2,具体的细节如下:

setOnRefreshLisner()以后,PullToRefreshListview会把OnRefreshListener保存到本地变量mOnRefreshListener中,等待刷新事件触发,就调用mOnRefreshListener中的OnRefresh()开启异步任务。

 

用户调用的最后一个方法onRefreshCompleteString

 

1当时数据更新完毕的时候调用的方法,通知控件数据更新完毕,控件进行合理的显示调整。

2,具体地,当调用上述方法并传入一个字符串类型数据以后,会调用两个方法

setlastUpdated(用户传入的字符串);

onRefreshComeplete();

 

下面按照调用顺序介绍pullToRefreshListView控件中定义的各个方法;

1,三个构造方法在获得该类对应控件的时候调用的,不在多说

2Init()在构造方法里调用,上面已经说过

3OnAttachedToWindow()在onDraw()之前调用,此处是为了将listview默认显示第二个(setSelection1));

4setAdaper()设置适配器以后时会调用的方法,此处同样是为了将listview默认显示第二条。

5onTouchEvent()当用户Touch到该控件的时候就会调用的方法:

此处,首先取得点击的y坐标,设置mBounceHackfalse

其次,对事件进行匹配,

如果是Action_up,就让滚动条可见,

如果,header可见并且状态不是正在刷新,分两种情况,

A;如果mRefreshView被全部拉出,而且现在的状态是RELEASE_TO_REFRESH那么就把状态改为   REFRESHING

然后调用prepareForRefresh();//做刷新时视图应该做的改变

onRefresh();//开启异步任务

 

B:如果mRefreshView只被拉出了一部分,就调用:

resetHeader();

setSelection(1);

 

如果是Action_Down: 记录  y坐标到mLastMotionY = y;

 

如果是ACTION_MOVE  

applyHeaderPadding(event);

6,下面就分析一下applyHeaderPadding(MotionEvent ev)  

根据ev事件中包含的滑动信息,得出应该有的padding,并setPadingmRefreshView上。(类似的resetHeaderPadding()是指把padding归零)

resetHeader()表示吧header弄到原始状态。)

7,最后就是onScroll onscrollstateChagede()

前者滚动状态和mRefreshView的高度判断如何动作,后者只是在state

SCROLL_STATE_IDLE的时候吧mBounceHack置为false。也就是说,mBounceHack仅仅表示飞速滑动状态下的状态,至于为什么要用这个变量我也不清楚。

 

至此整个流程已经基本明了了,当初始化该PullToRefreshListView控件以后,通过setOnRefreshListener()监听该控件的“Refresh”事件。

当用户滚动该控件的时候总是先触发,其中的onTouchEvent()事件,在该事件当中,会判断该listview应该有的状态,  然后当onScroll事件触发的时候,进行相关的控件显示动作,当用户拉到控件高度的时候触发异步任务,最后提示,加载完成,更新控件的显示。

 

其中关于老师认为很巧妙的两个ScrollListener

1首先要明白onscrollListener是在用户滚动了布局中的控件,控件滚动了以后会触发的事件,至于listview的滚动式无需我们操心的,我们只需要关系滚动的时候我们应该做什么酒行了。

2至于本pullToRefreshListView来说对外曝光了SetOnScrooListener()

同时他父类也有setOnScrollListener();所以如果该控件不复写这个setOnscrollListener()

当我们用这个类的实例调用该方法的时候就会调用父类的setonstrolllister()方法。吧onscrollListener设置到系统类中的monScrollListener

这样当用户触发absListView的滚动事件的时候就会调用刚刚定义的onstrolllistener中的方法

 

但是我们不但要对外曝光setOnscrollLisner()供使用该类实例的程序员监听滚动事件,

同时我们在定义这个类的时候也需要监听该滚动事件,因为我们不是系统,我们写的代码也是被调用的。

于是矛盾就来了,系统只会有一个mOnscrollListener实例,我们却又两处要对其进行监听

怎么解决呢?

 

它给出了这样一个解决方案。

即:复写setOnscrollListener  这样在程序员使用这个PulltoRefreshListView,并监听其滚动事件的时候,调用的setOnscrollLisner 就不在是父类中的setonscrollListener了而是复写过的,

这样在复写中的方法里吧传入的onScrollListenrer保存到本类中的monScrollListener

在本类对象监听到滚动事件的时候处理完自己的逻辑以后再调用mscrollLisner中相应的方法即可

 

这就是多处同时监听一个事件的方法。

原文地址:https://www.cnblogs.com/mayhelp/p/3413468.html