1. 程式人生 > 程式設計 >Android實現美團外賣底部導航欄動畫

Android實現美團外賣底部導航欄動畫

體驗了一下美團外賣的底部導航欄,感覺動畫很流暢,分割線被頂起,還有圖示的動畫,可能用的lottie,覺得分割線被頂起可以自己寫動畫,所以試著寫了一下 。

想自定義view點選實現動畫效果,自定義view的區域一定比背景需要被頂起的線要高,所以佈局如下:

開始繪製view,被頂起的曲線分三段,前後兩端曲線對稱的,用path繪製曲線,中間段繪製貝塞爾曲線。

那麼我們分別繪製三段曲線,用ValueAnimator實現效果,

private void initAnim() {
  value = startValue;
  animator = ValueAnimator.ofInt(startValue,halfValue,endValue);
//  animator.setInterpolator(new DecelerateInterpolator());
  animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
   @Override
   public void onAnimationUpdate(ValueAnimator valueAnimator) {
    value = (int) valueAnimator.getAnimatedValue();
    invalidate();
   }
  });
  animator.setDuration(ANIM_TIME);
  animator.start();
 }

動畫執行過程中有個回彈,那麼value的變化需要一箇中間值,

startValue = 0;
halfValue = -DensityUtils.dp2px(context,35);
endValue = -DensityUtils.dp2px(context,25);

在onDraw中繪製曲線程式碼如下,

rectF = new RectF((((float)width - (float)contentSize) / 2),lineToTop + value,(float) width - ((float)width - (float)contentSize) / 2,height + value);
 
 
  if (value < 0 ) {
   Path path = new Path();
   //繪製第一段圓弧
   path.moveTo(rectF.left - 20,lineToTop);
   float firstCubicHight = ((float) lineToTop - rectF.top) / 4;
   float end = (float) lineToTop - firstCubicHight;
   path.cubicTo(
     rectF.left - 10,(float) lineToTop - firstCubicHight / 16,rectF.left,(float) lineToTop - firstCubicHight / 12,rectF.left + 10,end
   );
 
   //繪製第二段圓弧
 
   path.quadTo(
     rectF.left + contentSize / 2,rectF.top * 0.9f,rectF.right - 10,end
   );
   //繪製第三段圓弧,和第一段對稱
 
   path.cubicTo(
     rectF.right,rectF.right + 10,rectF.right + 20,lineToTop
   );
 
   Path pathBg = new Path();
   pathBg.addPath(path);
 
   pathBg.lineTo(rectF.right + 20,height);
   pathBg.lineTo(rectF.left - 20,lineToTop);
   canvas.drawPath(pathBg,paintBg);//繪製白色背景
 
   canvas.drawPath(path,paintBgStroke);//繪製曲線
 
  }

最後在onDraw()中畫上圖片也用屬性動畫移動就成功啦。

因為有曲線銜接貝塞爾曲線,感覺弧度有時候改變曲線不是很流暢,大家應該會有更好的辦法 歡迎補充!

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。