超好看的下拉刷新动画Android代码实现

超好看的下拉刷新动画Android代码实现,第1张

概述最近看到了好多高端、大气、上档次的动画效果,如果给你的项目中加上这些动画,相信你的app一定很优秀,今天给大家分析一下来自Yalantis的一个超好看的下拉刷新动画。

最近看到了好多高端、大气、上档次的动画效果,如果给你的项目中加上这些动画,相信你的app一定很优秀,今天给大家分析一下来自Yalantis的一个超好看的下拉刷新动画。

首先我们看一下效果如何:

怎么样?是不是很高大上?接下来我们看一下代码

一、首先我们需要自定义刷新的动态RefreshVIEw(也就是下拉时候的头)
1.初始化头所占用的Dimens

private voID initiateDimens() {     mScreenWIDth = mContext.getResources().getdisplayMetrics().wIDthPixels;     mJettopOffset = mParent.getTotalDragdistance() * 0.5f;     mtop = -mParent.getTotalDragdistance();   } 

2.为头填充图片,设置图片的大小
分别为左边的云彩,右边的云彩,中间的云彩还有中间的飞机,飞机是带有动画的,下面会介绍飞机的动画

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.然后我们来画这个头

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 of 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 will be greater than 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 will draw    * @param y    - y position fot one of lines    * @param xOffset - x offset for on of 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 = (mScreenWIDth + xOffset) / (LOADING_ANIMATION_COEFFICIENT / SLOW_DOWN_ANIMATION_COEFFICIENT);     float time = mloadingAnimationTime;      // HORRIBLE Hack FOR REVERS ANIMATION THAT SHOulD WORK liKE RESTART ANIMATION     if (mLastAnimationTime - mloadingAnimationTime > 0) {       mInverseDirection = true;       // take time from 0 to end of animation time       time = (LOADING_ANIMATION_COEFFICIENT / SLOW_DOWN_ANIMATION_COEFFICIENT) - mloadingAnimationTime;     } else {       mNewWindSet = true;       mInverseDirection = false;     }      // Taking current x position of drawing wind     // For fully disappearing of line we should subtract wind line wIDth     float x = (mScreenWIDth - (time * cof)) + xOffset - mWindlinewidth;     float xEnd = x + mWindlinewidth;      canvas.drawline(x,xEnd,mWindPaint);   }    private voID drawSIDeClouds(Canvas canvas) {     Matrix matrixleftClouds = mMatrix;     Matrix matrixRightClouds = mAdditionalMatrix;     matrixleftClouds.reset();     matrixRightClouds.reset();      // Drag percent will 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 screen and we should drag them with content of ListVIEw     int cloudsVisibleposition = mParent.getTotalDragdistance() / 2 - mleftCloudsHeightCenter;      boolean needMoveCloudsWithContent = false;     if (dragYOffset < cloudsVisibleposition) {       needMoveCloudsWithContent = true;     }      float offsetRightX = mScreenWIDth - mRightClouds.getWIDth();     float offsetRightY = (needMoveCloudsWithContent         ? mParent.getTotalDragdistance() * dragPercent - mleftClouds.getHeight()         : dragYOffset)         + (overdrag ? mtop : 0);      float offsetleftX = 0;     float offsetleftY = (needMoveCloudsWithContent         ? mParent.getTotalDragdistance() * dragPercent - mleftClouds.getHeight()         : dragYOffset)         + (overdrag ? mtop : 0);      // Magic with animation on loading process     if (isRefreshing) {       if (checkCurrentAnimationPart(AnimationPart.FirsT)) {         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.THIRD) / 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,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 want kNow about how mach percent of over drag we done       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() - mFrontCloudHeightCenter;      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.SECOND) / LOADING_ANIMATION_COEFFICIENT) / 8;       } else if (checkCurrentAnimationPart(AnimationPart.THIRD)) {         sx = scale + (getAnimationPartValue(AnimationPart.THIRD) / LOADING_ANIMATION_COEFFICIENT) / 6;       } else if (checkCurrentAnimationPart(AnimationPart.FOURTH)) {         sx = scale + (getAnimationPartValue(AnimationPart.FOURTH) / 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)         - mJetHeightCenter;      if (isRefreshing) {       if (checkCurrentAnimationPart(AnimationPart.FirsT)) {         offsetY -= getAnimationPartValue(AnimationPart.FirsT);       } else if (checkCurrentAnimationPart(AnimationPart.SECOND)) {         offsetY -= getAnimationPartValue(AnimationPart.SECOND);       } else if (checkCurrentAnimationPart(AnimationPart.THIRD)) {         offsetY += getAnimationPartValue(AnimationPart.THIRD);       } else if (checkCurrentAnimationPart(AnimationPart.FOURTH)) {         offsetY += getAnimationPartValue(AnimationPart.FOURTH);       }     }      matrix.setTranslate(offsetX,offsetY);      if (dragPercent == 1.0f) {       matrix.preRotate(rotateAngle,mJetWIDthCenter,mJetHeightCenter);     }      canvas.drawBitmap(mJet,null);   } 

动画效果已经画好了,下面我们来看看怎么结合下拉刷新来调用吧?
二、我们还需要自定义一个PullToRefreshVIEw(下拉刷新)
1.我们的PullToRefreshVIEw这里需要继承VIEwGroup
我们先把刚才定义的刷新时的动画加进来

private RefreshVIEw mRefreshVIEw; <pre name="code" >private ImageVIEw mRefreshImageVIEw; <pre name="code" >mRefreshImageVIEw = new ImageVIEw(context);     mRefreshVIEw = new RefreshVIEw(getContext(),this);     mRefreshImageVIEw.setimageDrawable(mRefreshVIEw);      addVIEw(mRefreshImageVIEw); 

2.然后我们设置OntouchEvent()事件

@OverrIDe   public boolean ontouchEvent(@NonNull MotionEvent ev) {      if (!mIsBeingDragged) {       return super.ontouchEvent(ev);     }      final int action = MotionEventCompat.getActionMasked(ev);      switch (action) {       case MotionEvent.ACTION_MOVE: {         final int pointerIndex = MotionEventCompat.findPointerIndex(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;   } 

三、最后我们看怎样在Activity中使用这个下拉刷新控件
1.先看一下布局文件
这里是我们的下拉刷新空间嵌套着我们的ListVIEw,然后我们再给ListVIEw填充数据即可

<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.为ListVIEw填充数据
为了我们的效果比较好看,这里我们给ListVIEw的每一个item填充不同的颜色,看起来会比较高大上。

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(new SampleAdapter(this,R.layout.List_item,sampleList)); 

3.最后,我们再设置一下下拉刷新的监听事件就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);       }     }); 

怎么样?有没有很高大上啊?

大家可以动手实践一下,希望对大家的学习有所帮助。

总结

以上是内存溢出为你收集整理的超好看的下拉刷新动画Android代码实现全部内容,希望文章能够帮你解决超好看的下拉刷新动画Android代码实现所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1142042.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-31
下一篇2022-05-31

发表评论

登录后才能评论

评论列表(0条)

    保存