Super good-looking dropdown refresh animation Android code implementation _android

Source: Internet
Author: User
Tags abs gety new set

Recently saw a lot of high-end, atmosphere, the grade of animation effect, if you add these animations to your project, I believe your app must be very good, today to analyze a look from the yalantis of a very good-looking Drop-down refresh animation.

First, let's take a look at how it works:

What do you think? Is it very tall? Next we'll look at the code:

First, we need to customize the refreshed dynamic Refreshview (that is, the head of the dropdown)
1. Initialization of the head to occupy the Dimens

private void Initiatedimens () { 
    mscreenwidth = mcontext.getresources (). Getdisplaymetrics (). Widthpixels; 
    Mjettopoffset = Mparent.gettotaldragdistance () * 0.5f; 
    Mtop =-mparent.gettotaldragdistance (); 
  } 

2. Fill the picture for the head, set the size of the picture
The clouds on the left, the clouds on the right, the clouds in the middle and the plane in the middle, the plane is animated, and the animation of the airplane is described below.

private void Createbitmaps () { 
    mleftclouds = Bitmapfactory.decoderesource (Mcontext.getresources (), R.drawable.clouds_left); 
    Mrightclouds = Bitmapfactory.decoderesource (Mcontext.getresources (), r.drawable.clouds_right); 
    Mfrontclouds = Bitmapfactory.decoderesource (Mcontext.getresources (), r.drawable.clouds_center); 
    Mjet = Bitmapfactory.decoderesource (Mcontext.getresources (), r.drawable.airplane); 
 
    Mjetwidthcenter = Mjet.getwidth ()/2; 
    Mjetheightcenter = Mjet.getheight ()/2; 
    Mfrontcloudwidthcenter = Mfrontclouds.getwidth ()/2; 
    Mfrontcloudheightcenter = Mfrontclouds.getheight ()/2; 
 
    Mrightcloudswidthcenter = Mrightclouds.getwidth ()/2; 
    Mrightcloudsheightcenter = Mrightclouds.getheight ()/2; 
    Mleftcloudswidthcenter = Mleftclouds.getwidth ()/2; 
    Mleftcloudsheightcenter = Mleftclouds.getheight ()/2; 
  

3. Then we'll draw this head.

public void Draw (@NonNull Canvas Canvas) {final int savecount = Canvas.save (); 
    DRAW BACKGROUND. 
 
    Canvas.drawcolor (Mcontext.getresources (). GetColor (R.color.sky_background)); if (isrefreshing) {//Set up new set ' wind ' while (Mwinds.size () < Wind_set_amount) {float y 
        = (float) (Mparent.gettotaldragdistance ()/(Math.random () * random_y_coefficient)); 
 
        float x = Random (Min_wind_x_offset, max_wind_x_offset); 
          Magic with checking interval between winds if (mwinds.size () > 1) {y = 0; while (y = = 0) {Float tmp = (float) (Mparent.gettotaldragdistance ()/(Math.random () * random_y_coefficient) 
 
            ); For (Map.entry<float, float> wind:mWinds.entrySet ()) {//We want that interval'll be greater tha N Fifth part of draggable distance if (Math.Abs (Wind.getkey ()-tmp) > Mparent.gettotaldragdistance ()/ Random_y_coefficient) {y = tmp; 
                else {y = 0; 
              Break 
        }}} mwinds.put (Y, x); 
      Drawwind (canvas, y, x);  }//Draw current set of Wind if (Mwinds.size () >= Wind_set_amount) {for (map.entry<float, 
        Float> Wind:mWinds.entrySet ()) {Drawwind (canvas, Wind.getkey (), Wind.getvalue ()); 
        }//We should to create new set of winds if (minversedirection && mnewwindset) { 
        Mwinds.clear (); 
        Mnewwindset = false; 
      Mwindlinewidth = Random (Min_wind_line_width, max_wind_line_width); 
    }//needed for checking direction mlastanimationtime = Mloadinganimationtime; 
    } drawjet (canvas); 
    Drawsideclouds (canvas); 
 
    Drawcenterclouds (canvas); 
  Canvas.restoretocount (Savecount); 
 }
/** * Draw Wind on loading animation * * @param canvas-area where we'll Draw * @param y-y Positi On fot One of lines * @param xoffset-x offset for on lines/private void Drawwind (Canvas Canvas, float y , float Xoffset) {/* We should multiply current animation time with this coefficient for taking all screen width in  Time removing slowing of animation with dividing on {@LINK #SLOW_DOWN_ANIMATION_COEFFICIENT} and we should don ' t Forget about distance that should ' fly ' line, that depend on screen of device and X offset/float COF = (mscre 
    Enwidth + xoffset)/(loading_animation_coefficient/slow_down_animation_coefficient); 
 
    float time = mloadinganimationtime; Horrible HACK for revers ANIMATION this SHOULD WORK like restart if (ANIMATION 
      Iontime > 0) {minversedirection = true; Take time from 0 to end of animation time = (Loading_animation_coefficient/slow_down_animation_coefficient)-Mloadinganimationtime; 
      else {Mnewwindset = true; 
    Minversedirection = false; }//taking current x position of drawing wind//for fully disappearing the line we should subtract wind line 
    width float x = (Mscreenwidth-(Time * cof)) + xoffset-mwindlinewidth; 
 
    float xend = x + mwindlinewidth; 
  Canvas.drawline (x, y, xend, y, mwindpaint); 
    } private void Drawsideclouds (Canvas Canvas) {Matrix matrixleftclouds = Mmatrix; 
    Matrix matrixrightclouds = Madditionalmatrix; 
    Matrixleftclouds.reset (); 
 
    Matrixrightclouds.reset (); 
 
    Drag percent would newer get more then 1 here float dragpercent = math.min (1f, Math.Abs (mpercent)); 
 
    Boolean Overdrag = false; 
    But we check here for Overdrag if (Mpercent > 1.0f) {Overdrag = true; 
    float scale; 
    float Scalepercentdelta = dragpercent-scale_start_percent; if (Scalepercentdelta > 0) {float scalepercent = Scalepercentdelta/(1.0f-scale_start_percent); 
    Scale = Side_clouds_initial_scale + (side_clouds_final_scale-side_clouds_initial_scale) * scalepercent; 
    else {scale = Side_clouds_initial_scale; 
 
    }//Current y position of clouds float Dragyoffset = mparent.gettotaldragdistance () * (1.0f-dragpercent); Position where clouds fully visible on screens and we should drag them with content of ListView int CLOUDSVI 
 
    Sibleposition = Mparent.gettotaldragdistance ()/2-mleftcloudsheightcenter; 
    Boolean needmovecloudswithcontent = false; 
    if (Dragyoffset < cloudsvisibleposition) {needmovecloudswithcontent = true; 
    float offsetrightx = Mscreenwidth-mrightclouds.getwidth (); float offsetrighty = (needmovecloudswithcontent mparent.gettotaldragdistance () * Dragpercent-mleftclouds.geth Eight (): Dragyoffset) + (Overdrag?mtop:0); 
    float OFFSETLEFTX = 0; float offsetlefty = (needmovecloudswithcontent mparent.gettotaldragdistance () * dragpercent-mleftclouds.gethe 
 
    Ight (): Dragyoffset) + (Overdrag? mtop:0); Magic with animation on loading process if (isrefreshing) {if Checkcurrentanimationpart (Animationpart.fir 
        ST)) {offsetlefty + = Getanimationpartvalue (animationpart.first)/y_side_clouds_slow_down_cof; 
      OFFSETRIGHTX-= Getanimationpartvalue (Animationpart.first)/x_side_clouds_slow_down_cof; else if (Checkcurrentanimationpart (Animationpart.second)) {offsetlefty + = Getanimationpartvalue (AnimationPart. 
        SECOND)/Y_SIDE_CLOUDS_SLOW_DOWN_COF; 
      OFFSETRIGHTX-= Getanimationpartvalue (animationpart.second)/x_side_clouds_slow_down_cof; else if (Checkcurrentanimationpart (Animationpart.third)) {offsetlefty-= Getanimationpartvalue (AnimationPart.T Hird)/Y_SIDE_CLOUDS_SLOW_DOWN_COF;
        OFFSETRIGHTX + = Getanimationpartvalue (animationpart.third)/x_side_clouds_slow_down_cof; else if (Checkcurrentanimationpart (Animationpart.fourth)) {offsetlefty-= Getanimationpartvalue (AnimationPart. 
        Fourth)/X_SIDE_CLOUDS_SLOW_DOWN_COF; 
      OFFSETRIGHTX + = Getanimationpartvalue (Animationpart.fourth)/y_side_clouds_slow_down_cof; 
    } matrixrightclouds.postscale (scale, scale, mrightcloudswidthcenter, mrightcloudsheightcenter); 
 
    Matrixrightclouds.posttranslate (OFFSETRIGHTX, offsetrighty); 
    Matrixleftclouds.postscale (scale, scale, mleftcloudswidthcenter, mleftcloudsheightcenter); 
 
    Matrixleftclouds.posttranslate (OFFSETLEFTX, offsetlefty); 
    Canvas.drawbitmap (Mleftclouds, matrixleftclouds, NULL); 
  Canvas.drawbitmap (Mrightclouds, matrixrightclouds, NULL); 
    } private void Drawcenterclouds (Canvas Canvas) {Matrix matrix = Mmatrix; 
    Matrix.reset (); float dragpercent = math.min (1f, Math.Abs (mpercent)); 
    float scale; 
    float overdragpercent = 0; 
 
    Boolean Overdrag = false; 
      if (Mpercent > 1.0f) {Overdrag = true; 
    Here we are want know about how Mach percent the over drag we do overdragpercent = Math.Abs (1.0f-mpercent); 
    float Scalepercentdelta = dragpercent-scale_start_percent; 
      if (Scalepercentdelta > 0) {float scalepercent = Scalepercentdelta/(1.0f-scale_start_percent); 
    Scale = Center_clouds_initial_scale + (center_clouds_final_scale-center_clouds_initial_scale) * scalePercent; 
    else {scale = Center_clouds_initial_scale; 
    float parallaxpercent = 0; 
    Boolean parallax = false; 
    Current y position of clouds float Dragyoffset = mparent.gettotaldragdistance () * dragpercent; Position when should start parallax scrolling int startparallaxheight = mparent.gettotaldragdistance ()-Mfrontclo 
 
    Udheightcenter; if (Dragyoffset > StartparallaxhEight) {parallax = true; 
    Parallaxpercent = Dragyoffset-startparallaxheight; 
    float OffsetX = (MSCREENWIDTH/2)-mfrontcloudwidthcenter; 
        float OffsetY = Dragyoffset-(parallax? Mfrontcloudheightcenter + parallaxpercent:mfrontcloudheightcenter) 
 
    + (Overdrag mtop:0); float SX = Overdrag? 
    Scale + OVERDRAGPERCENT/4: scale; Float sy = Overdrag? 
 
    Scale + OVERDRAGPERCENT/2: scale; if (isrefreshing &&!overdrag) {if (Checkcurrentanimationpart (Animationpart.first)) {SX = scale 
      -(Getanimationpartvalue (Animationpart.first)/loading_animation_coefficient)/8; else if (Checkcurrentanimationpart (Animationpart.second)) {SX = scale-(Getanimationpartvalue (ANIMATIONPART.S 
      Econd)/loading_animation_coefficient)/8; else if (Checkcurrentanimationpart (Animationpart.third)) {SX = scale + (Getanimationpartvalue (animationpart.th IRD)/Loading_animation_coefficient)/6; else if (Checkcurrentanimationpart (Animationpart.fourth)) {SX = scale + (Getanimationpartvalue (animationpart.f 
      Ourth)/loading_animation_coefficient)/6; 
    SY = SX; 
    Matrix.postscale (SX, SY, Mfrontcloudwidthcenter, Mfrontcloudheightcenter); 
 
    Matrix.posttranslate (OffsetX, OffsetY); 
  Canvas.drawbitmap (mfrontclouds, matrix, NULL); 
    } private void Drawjet (Canvas Canvas) {Matrix matrix = Mmatrix; 
 
    Matrix.reset (); 
    float dragpercent = mpercent; 
 
    float Rotateangle = 0; Check Overdrag if (dragpercent > 1.0f &&!mendofrefreshing) {rotateangle = (dragpercent% 1) * 
      10; 
    Dragpercent = 1.0f; 
 
    float OffsetX = ((Mscreenwidth * dragpercent)/2)-mjetwidthcenter; Float OffsetY = Mjettopoffset + (mparent.gettotaldragdistance ()/2) * (1.0f-dragpercent)-M 
 
    Jetheightcenter; if (isrefreshing) {if (checkCurrentanimationpart (Animationpart.first)) {OffsetY-= Getanimationpartvalue (Animationpart.first); else if (Checkcurrentanimationpart (Animationpart.second)) {OffsetY-= Getanimationpartvalue (Animationpart.seco 
      ND); else if (Checkcurrentanimationpart (Animationpart.third)) {OffsetY + = Getanimationpartvalue (animationpart.third 
      ); else if (Checkcurrentanimationpart (Animationpart.fourth)) {OffsetY + = Getanimationpartvalue (animationpart.four 
      TH); 
 
    } matrix.settranslate (OffsetX, OffsetY); 
    if (dragpercent = = 1.0f) {matrix.prerotate (Rotateangle, Mjetwidthcenter, Mjetheightcenter); 
  } canvas.drawbitmap (Mjet, matrix, NULL); 

 }

The animation effect has been painted, let's see how to combine the Drop-down refresh to call it?
Second, we also need to customize a Pulltorefreshview (dropdown refresh)
1. We need to inherit the Pulltorefreshview here ViewGroup
Let's start by adding the animation that we just defined in the refresh time.

Private Refreshview Mrefreshview; 
<pre name= "code" class= "java" >private ImageView Mrefreshimageview; 
<pre name= "code" class= "java" >mrefreshimageview = new ImageView (context); 
    Mrefreshview = new Refreshview (GetContext (), this); 
    Mrefreshimageview.setimagedrawable (Mrefreshview); 
 
    AddView (Mrefreshimageview); 

2. Then we set up the Ontouchevent () event

@Override public boolean ontouchevent (@NonNull motionevent ev) {if (!misbeingdragged) {return Super.on 
    TouchEvent (EV); 
 
    Final int action = motioneventcompat.getactionmasked (EV); Switch (action) {case motionevent.action_move: {final int pointerindex = Motioneventcompat.findpointerin 
        Dex (EV, Mactivepointerid); 
        if (Pointerindex < 0) {return false; 
        Final float y = motioneventcompat.gety (ev, POINTERINDEX); 
        Final float Ydiff = y-minitialmotiony; 
        Final float scrolltop = Ydiff * drag_rate; 
        Mcurrentdragpercent = scrolltop/mtotaldragdistance; 
        if (Mcurrentdragpercent < 0) {return false; 
        float boundeddragpercent = math.min (1f, Math.Abs (mcurrentdragpercent)); 
        float Extraos = Math.Abs (scrolltop)-mtotaldragdistance; 
        float slingshotdist = mtotaldragdistance; float tensionslingshotpercent = Math.max (0, Math.min (Extraos, Slingshotdist * 2)/slingshotdist); float tensionpercent = (float) (TENSIONSLINGSHOTPERCENT/4)-Math.pow ((TENSIONSLINGSHOTPERCENT/4), 2) 
        * 2f; 
        float Extramove = (slingshotdist) * TENSIONPERCENT/2; 
 
        int targety = (int) ((slingshotdist * boundeddragpercent) + extramove); 
        Mrefreshview.setpercent (mcurrentdragpercent); 
        Settargetoffsettop (Targety-mcurrentoffsettop, true); 
      Break 
        Case MotionEventCompat.ACTION_POINTER_DOWN:final int index = motioneventcompat.getactionindex (EV); 
        Mactivepointerid = Motioneventcompat.getpointerid (EV, index); 
      Break 
        Case MotionEventCompat.ACTION_POINTER_UP:onSecondaryPointerUp (EV); 
      Break 
          Case MotionEvent.ACTION_UP:case Motionevent.action_cancel: {if (Mactivepointerid = = Invalid_pointer) { 
        return false; Final int pointerindex = Motioneventcompat.findpointerindex (EV, Mactivepointerid); 
        Final float y = motioneventcompat.gety (ev, POINTERINDEX); 
        Final float overscrolltop = (y-minitialmotiony) * drag_rate; 
        Misbeingdragged = false; 
        if (Overscrolltop > Mtotaldragdistance) {setrefreshing (True, true); 
          else {mrefreshing = false; 
        Animateoffsettoposition (manimatetostartposition); 
        } Mactivepointerid = Invalid_pointer; 
      return false; 
  } return true; 
 }

Third, finally we see how to use this Drop-down to refresh the control in the activity
1. Look at the layout file first
Here is our dropdown flush space nesting our listview, and then we fill the ListView with data

<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android" 
  xmlns:tools= "http:// Schemas.android.com/tools " 
  android:layout_width=" match_parent " 
  android:layout_height=" Match_parent " 
  tools:context= ". Pulltorefreshactivity "> 
 
  <com.hankkin.animationpulltorefreshdemo.pulltorefreshview 
    android:id=" @+ Id/pull_to_refresh " 
    android:layout_width=" match_parent " 
    android:layout_height=" match_parent "> 
 
    <listview 
      android:id= "@+id/list_view" 
      android:divider= "@null" 
      android:dividerheight= "0DP" 
      android:fadingedge= "None" 
      android:layout_width= "match_parent" 
      android:layout_height= "Match_ Parent "/> 
 
  </com.hankkin.AnimationPullToRefreshDemo.PullToRefreshView> 
 
</relativelayout > 

2. Populating data for ListView
In order to our effect is more good-looking, here we give ListView each item fills different color, looks like will be bigger.

Map<string, integer> map; 
    list<map<string, integer>> samplelist = new arraylist<map<string, integer>> (); 
 
 
    int[] Colors = { 
        R.color.saffron, 
        r.color.eggplant, 
        R.color.sienna}; 
 
    Int[] Tripnames = { 
        R.string.trip_to_india, 
        r.string.trip_to_italy, 
        R.string.trip_to_indonesia}; 
 
    for (int i = 0; i < tripnames.length i++) { 
      map = new hashmap<string, integer> (); 
      Map.put (Sampleadapter.key_name, tripnames[i]); 
      Map.put (Sampleadapter.key_color, colors[i]); 
      Samplelist.add (map); 
 
    ListView ListView = (ListView) Findviewbyid (R.id.list_view); 
    Listview.setadapter (This, R.layout.list_item, Samplelist) (new Sampleadapter); 

3. Finally, let's set up the drop-down-Refresh listening event OK

Mpulltorefreshview = (Pulltorefreshview) Findviewbyid (R.id.pull_to_refresh); 
    Mpulltorefreshview.setonrefreshlistener (New Pulltorefreshview.onrefreshlistener () { 
      @Override public 
      Void Onrefresh () { 
        mpulltorefreshview.postdelayed (new Runnable () { 
          @Override public 
          void Run () { 
            Mpulltorefreshview.setrefreshing (FALSE); 
          } 
        , Refresh_delay); 
      }} 
    ; 

What do you think? Is there a big man?

We can practice a little bit, hope to be helpful to everybody's study.

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.