Open source Android-pulltorefresh drop-down refresh source analysis

Source: Internet
Author: User
Tags call back gety

Pulltorefresh This library is very at most, GitHub today mainly analyze the implementation of the source code.

We analyze it through the dropdown refresh of the ListView, other similar.

The entire dropdown refresh parent view is LinearLayout, adding header view, Footer view, and ListView in LinearLayout

Pulltorefreshbase is the parent class that extends the linearlayout horizontal layout if we use the ListView need to watch subclass Pulltorefreshadapterviewbase-Pulltorefreshlistv Iew


Initialization code in the Pulltorefreshbase init method

Key code:

Refreshable view//by passing the attrs, we can add listview/gridview params via Xmlmrefreshableview = Createrefreshabl Eview (context, attrs);//Addrefreshableview (context, Mrefreshableview) via sub-class View,listview or scrollview;// Add view to Layout//We need to create now layouts now  creates header and footer view, default is invisible, to add to parent window Mheaderlayout = Createloadinglayout (context, Mode.pull_from_start, a); mfooterlayout = createloadinglayout (Context, mode.pull_from_ END, a); Handlestyledattributes (a);//Add Loadingview effect, here is to add the view to the ListView Headerview inside to Updateuiformode (); Add a layout to the parent view

protected void Updateuiformode () {final Linearlayout.layoutparams LP = Getloadinglayoutlayoutparams ();//Remove Header, And then the add Header Loading View again if neededif (this = = Mheaderlayout.getparent ()) {Removeview (mheaderlayout);} if (Mmode.showheaderloadinglayout ()) {addviewinternal (mheaderlayout, 0, LP);//Add view to linearlayout}//Remove Footer, And then add Footer Loading View again if neededif (this = = Mfooterlayout.getparent ()) {Removeview (mfooterlayout);} if (Mmode.showfooterloadinglayout ()) {addviewinternal (mfooterlayout, LP);//Add view to linearlayout}//Hide Loading Viewsrefreshloadingviewssize ();//Hide Headerview, its practical is padding the way to set negative to the top of the screen//If we ' re not using Mode.both, set Mcurrentmode to Mmode, otherwise//set it to pull Downmcurrentmode = (Mmode! = Mode.both)? MMode:Mode.PULL_FROM_START;}

There are 2 Loadingview, one is added to the LinearLayout, and the other is added to the header of the ListView itself.

See where the Handlestyledattributes method is positioned to sub-category replication

Framelayout frame = new Framelayout (GetContext ());
Mheaderloadingview = Createloadinglayout (GetContext (), Mode.pull_from_start, a);
Mheaderloadingview.setvisibility (View.gone);
Frame.addview (Mheaderloadingview, LP);
Mrefreshableview.addheaderview (frame, null, FALSE);//Add Loadingview to the ListView header

Headerview altogether has 2 loadingview, one is added to LinearLayout one is added to the ListView Headerview
The Addviewinternal method is to join the LinearLayout parent class


See loadinglayout There are 2 kinds of fliploadinglayout and rotateloadinglayout we use to rotate the loading animation
A rotated picture on the left and a text and time hint on the right

The first loadinglayout main display: drop-down refresh, release to refresh
The second loadinglayout shows the text after letting go: loading ...

Structure is like this



When the UI is initialized well, take a look at the Ontouch drop-down capture event


Public Final Boolean ontouchevent (Motionevent event) {if (!ispulltorefreshenabled ()) {return false;} If we ' re refreshing, and the flag is set. Eat the Eventif (!mscrollingwhilerefreshingenabled && isrefreshing ()) {return true;} if (event.getaction () = = Motionevent.action_down && event.getedgeflags ()! = 0) {return false;} Switch (event.getaction ()) {case Motionevent.action_move: {if (misbeingdragged) {mlastmotiony = Event.gety (); Mlastmotionx = Event.getx ();p ullevent ();//start pull down, move return true;} break;} Case Motionevent.action_down: {if (Isreadyforpull ()) {//press Start dropdown mlastmotiony = Minitialmotiony = Event.gety (); Mlastmotionx = Minitialmotionx = Event.getx (); return true;} break;} Case MotionEvent.ACTION_CANCEL:case motionevent.action_up: {//stop pull down when if (misbeingdragged) {misbeingdragged = False;if (Mstate = = state.release_to_refresh&& (null! = Monrefreshlistener | | null! = MONREFRESHLISTENER2)) {SetState (state.refreshing, true);//Drop the finger to start the callback, execute our callback task return true;} If we ' re alReady refreshing, just scroll back to the TOPIF (Isrefreshing ()) {Smoothscrollto (0); return true;} If We haven ' t returned by here and then we ' re not in a state//to pulled, so just resetsetstate (State.reset); Revert to the original UI state return true;} Break;}} return false;}


Look at the Pullevent method private void Pullevent () {final int newscrollvalue;final int itemdimension;final float initialmotionvalue, Lastmotionvalue;switch (Getpulltorefreshscrolldirection ()) {case horizontal:initialmotionvalue = MInitialMotionX; Lastmotionvalue = Mlastmotionx;break;case VERTICAL:default:initialMotionValue = Minitialmotiony;lastmotionvalue = Mlastmotiony;break;} Calculate how many switch moves the dropdown (mcurrentmode) {case pull_from_end://pull-up NewScrollValue = Math.Round (Math.max (Initialmotionvalue- Lastmotionvalue, 0)/friction); itemdimension = getFooterSize (); Break;case pull_from_start://drop-down default: NewScrollValue = Math.Round (math.min (initialmotionvalue-lastmotionvalue, 0)/friction); itemdimension = GetHeaderSize (); break;} Show Headerview get moved value, can let Loadingview show Setheaderscroll (NewScrollValue); if (NewScrollValue! = 0 &&! Isrefreshing ()) {Float scale = Math.Abs (newscrollvalue)/(float) itemdimension;switch (mcurrentmode) {case Pull_from_ END:mFooterLayout.onPull (scale); Break;case pull_from_start:dEfault:mHeaderLayout.onPull (scale);//rotate the loading image on the left, display text and pictures This place will eventually execute the Onpullimpl method break in Loadinglayout;} The update status includes 2 in the release press Touch, and also the touch if the hands are not released if (mstate! = State.pull_to_refresh && itemdimension >= math.abs ( NewScrollValue)) {setState (State.pull_to_refresh);} else if (mstate = = State.pull_to_refresh && itemdimension & Lt Math.Abs (NewScrollValue)) {setState (State.release_to_refresh);//pull down and let go.}}}



And look at the Setheaderscroll method code protected final void Setheaderscroll (int value) {if (DEBUG) {log.d (Log_tag, "setheaderscroll:" + V Alue);} if (DEBUG) {log.d (Log_tag, "Setheaderscroll:" + value);} Clamp value to with pull scroll rangefinal int maximumpullscroll = Getmaximumpullscroll (); value = Math.min (maximumpulls Croll, Math.max (-maximumpullscroll, value)), if (mlayoutvisibilitychangesenabled) {if (value < 0) {// There is a displacement to show mheaderlayout.setvisibility (view.visible);} else if (value > 0) {<span style= "font-family:arial, Helvetica, Sans-serif;" >//has a displacement to show </span>mfooterlayout.setvisibility (view.visible);} else {mheaderlayout.setvisibility (view.invisible); mfooterlayout.setvisibility (view.invisible);}} if (use_hw_layers) {/** * use a Hardware Layer on the refreshable View if we've scrolled at * all. We don ' t use them on the Header/footer views as they change * often, which would negate any HW layer performance boost. */viewcompat.setlayertype (mrefreshableviewwrapper, Value! = 0?) View.LAYER_TYPE_HARDWARE:View.LAYER_TYPE_NONE);} Back to the most primitive scrollTo the most commonly used mobile layout switch (getpulltorefreshscrolldirection ()) {case Vertical:scrollto (0, value); break;case Horizontal:scrollto (value, 0); break;}}

SetState (state.refreshing, true);//Pull the top down, execute the Onrefreshing method, and call back the task interface we implemented, which is Onrefreshlistener


protected void Onrefreshing (final Boolean doscroll) {if (Mmode.showheaderloadinglayout ()) {mheaderlayout.refreshing () ;} if (Mmode.showfooterloadinglayout ()) {mfooterlayout.refreshing ();} if (doscroll) {if (mshowviewwhilerefreshing) {//Call Refresh Listener when the Scroll have Finishedonsmoothscrollfinishedl Istener listener = new Onsmoothscrollfinishedlistener () {@Overridepublic void onsmoothscrollfinished () { Callrefreshlistener ();//callback Interface Execution}};switch (mcurrentmode) {case Manual_refresh_only:case Pull_from_end:smoothscrollto (getFooterSize (), listener); Break;default:case Pull_from_start:smoothscrollto (-getheadersize (), listener); break;}} else {smoothscrollto (0);//Return to original position}} else {//We ' re not scrolling, so just call Refresh Listener Nowcallrefreshlistener (); /callback Interface Execution}}



private void Callrefreshlistener () {if (null! = Monrefreshlistener) {Monrefreshlistener.onrefresh (this);//callback} else if ( Null! = MOnRefreshListener2) {//This is the case of pull-up, drop-down all, use onrefreshlistener2if (Mcurrentmode = = Mode.pull_from_start) { Monrefreshlistener2.onpulldowntorefresh (this);} else if (Mcurrentmode = = mode.pull_from_end) {Monrefreshlistener2.onpulluptorefresh (this);}}}

Summary: The status includes the drop-down refresh, let go refresh, is refreshing, loading hidden. Moving the UI is also a scrollto of the most basic code. Animation section can see the loadinglayout of the 2 sub-classes

The main thing is that there are many details that are not analyzed. Please say thank you if you have any questions.



Open source Android-pulltorefresh drop-down refresh source analysis

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.