欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android中模仿抖音加載框之兩顆小球轉(zhuǎn)動效果

 更新時間:2018年09月06日 10:42:11   作者:勇朝陳  
這篇文章主要介紹了Android仿抖音加載框之兩顆小球轉(zhuǎn)動控件,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下

安卓版抖音v2.5加載框:

效果圖如下所示:

抖音加載框

本控件效果圖:

本控件

使用方法

源碼地址:Android仿抖音加載框之兩顆小球轉(zhuǎn)動控件

1、xml引用:

 <com.douyinloadingview.DYLoadingView
  android:id="@+id/dy3"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:background="#000000"
  app:color1="#FF00EEEE"
  app:color2="#FFFF4040"
  app:....(其他可選屬性) />

2、java使用:

 @BindView(R.id.dy1)
 DYLoadingView dy1;
 @OnClick(R.id.b1)
 void start() {
 dy1.setXXXXX; //設(shè)置屬性(可選)
 dy1.start(); //開始動畫
 }
 @OnClick(R.id.b2)
 void stop() {
 dy1.stop(); //停止動畫
 }

就醬。

可用屬性

名稱 對應(yīng)xml屬性 對應(yīng)java方法 默認值
球1半徑 radius1 setRadius() 6dp
球2半徑 radius2 setRadius() 6dp
兩球間隔 gap setRadius() 0.8dp
球1顏色 color1 setColors() 0XFFFF4040
球2顏色 color2 setColors() 0XFF00EEEE
疊加色 mixColor setColors() 0XFF000000
從右往左移動時小球最大縮放倍數(shù) rtlScale setScales() 0.7f
從左往右移動時小球最大縮放倍數(shù) ltrScale setScales() 1.3f
一次移動動畫時長 duration setDuration() 350ms
一次移動動畫后停頓時長 pauseDuration setDuration() 80ms
動畫進度在[0,scaleStartFraction]期間,小球大小逐漸縮放 scaleStartFraction setStartEndFraction() 0.2f
動畫進度在[scaleEndFraction,1]期間,小球大小逐漸恢復(fù) scaleEndFraction setStartEndFraction() 0.8f

(rtl = right to left, ltr = left to right)

部分屬性說明:

•color格式為32位ARGB
•scaleStartFraction范圍[0,0.5];scaleEndFraction范圍[0.5,1]
•假設(shè)ltrScale = 1.3,scaleStartFraction = 0.2,scaleEndFraction = 0.8;那么實際效果就是一顆小球從左邊開始向右移動

期間,進度在0%~20%時半徑逐漸從1倍放大到1.3倍,在20%~80%期間大小保持1.3倍,在80%~100%時半徑逐漸從1.3倍恢復(fù)至1倍

實現(xiàn)思路

要讓小球動,當然要有一個動畫,通過動畫來獲得一個進度百分比fraction,然后小球在動畫過程中的坐標、大小就可以通過這個值來計算:

   

 private void initAnim() {
 fraction = 0.0f;
 stop();
 anim = ValueAnimator.ofFloat(0.0f, 1.0f);
 anim.setDuration(duration);
 if (pauseDuration > 0) {
  anim.setStartDelay(pauseDuration);
  anim.setInterpolator(new AccelerateDecelerateInterpolator());
 } else {
  anim.setRepeatCount(ValueAnimator.INFINITE);
  anim.setRepeatMode(ValueAnimator.RESTART);
  anim.setInterpolator(new LinearInterpolator());
 }
 anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
  @Override
  public void onAnimationUpdate(ValueAnimator animation) {
  fraction = animation.getAnimatedFraction();
  invalidate();
  }
 });
 anim.addListener(new AnimatorListenerAdapter() {
  @Override
  public void onAnimationStart(Animator animation) {
  isLtr = !isLtr;
  }
  @Override
  public void onAnimationRepeat(Animator animation) {
  isLtr = !isLtr;
  }
  @Override
  public void onAnimationCancel(Animator animation) {
  isAnimCanceled = true;
  }
  @Override
  public void onAnimationEnd(Animator animation) {
  if (!isAnimCanceled) {
   anim.start();
  }
  }
 });
 }

代碼中看到,如果小球一次移動后不需要停頓(pauseDuration = 0),那么直接通過anim.setRepeatCount(ValueAnimator.INFINITE)讓動畫無限循環(huán),否則的話就要通過anim.setStartDelay(pauseDuration)來設(shè)置停頓時間,然后在監(jiān)聽的onAnimationEnd里重啟動畫,以此實現(xiàn)每一次移動后小球能停頓一定時間。在onAnimationUpdate里,我們記錄了當前動畫百分比fraction,然后通過invalidate()重繪,在之后的onDraw里將通過該值畫出小球。另外,每次動畫開始時(或是重復(fù)時),會將isLtr取反,這個標志位的作用是標明當前哪顆球在【從左往右】移動,因為兩顆球的顏色、初始半徑是不一樣的嘛,onDraw里畫小球時是需要這個標志位協(xié)助的。

有了動畫進度fraction和標志位isLtr后,就可以在onDraw里畫出小球了。

**首先要計算小球當前的坐標**。y坐標永遠是固定的,不談,x坐標隨著`fraction`的變化而變化。兩顆球之間最遠距離為球1半徑+球2半徑+兩球間隔,即`distance = gap + radius1 + radius2;`,這個值就是兩顆球的移動范圍,由此可計算出,當前【從左往右】移動的小球的x坐標和當前【從右往左】移動的小球x坐標分別為:

float ltrX = getMeasuredWidth() / 2.0f - distance / 2.0f;
ltrX = ltrX + (distance * fraction);
float rtlX = getMeasuredWidth() / 2.0f + distance / 2.0f;
rtlX = rtlX - (distance * fraction);

**接下來要計算小球當前的大小**。小球的大小也是隨著動畫進度變化的,上面已經(jīng)說明了`scaleStartFraction`和`scaleEndFraction`屬性的含義。 以當前小球【從左往右】移動為例,當動畫進度為0時,小球大小為初始1倍大??;當動畫進度到scaleStartFraction時,小球大小將縮放到`ltrScale`倍,當動畫進度為[scaleStartFraction,scaleEndFraction]范圍時,小球大小保持`ltrScale`倍,當動畫進度到[scaleEndFraction,1]范圍時,小球則從`ltrScale`倍逐漸恢復(fù)至1倍。 為了便于計算,首先將`[0,scaleStartFraction]`轉(zhuǎn)換為`[0,1.0]`的真實百分比,根據(jù)`y = kx + b`(就這么個入門公式。。我都要在紙上算一遍T-T),可以得出:`float scaleFraction = 1.0f / scaleStartFraction * fraction; `,有了這個真實百分比,那么該區(qū)間里小球當前半徑就好計算了:

ltrBallRadius = ltrInitRadius * (1 + (ltrScale - 1) * scaleFraction);
rtlBallRadius = rtlInitRadius * (1 + (rtlScale - 1) * scaleFraction);

應(yīng)該好懂的吧。另外[scaleEndFraction,1]區(qū)間里小球當前半徑計算思路是一樣的,不談。

最后就是要畫出小球。這里主要是如何畫出實現(xiàn)兩球疊加的部分的顏色。

 思路1:通過xfermode方式實現(xiàn):

xfermode

從上圖可以看出用Darken、Lighten、Screen模式可以做到讓疊加處上色,但是顏色不能自定義。

 思路2:通過path的OP操作實現(xiàn)(API19):

op

(圖片摘自http://www.gcssloop.com/customview/Path_Over

 因此,可以先構(gòu)造兩個小球的Path,然后再將這兩個Path進行INTERSECT操作,即可獲得疊加處的Path,這樣就可以做到自定義疊加處的顏色了。

onDraw完整代碼:

@Override
 protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);
 float centerY = getMeasuredHeight() / 2.0f;
 float ltrInitRadius, rtlInitRadius;
 Paint ltrPaint, rtlPaint;
 //確定當前【從左往右】移動的是哪顆小球
 if (isLtr) {
  ltrInitRadius = radius1;
  rtlInitRadius = radius2;
  ltrPaint = paint1;
  rtlPaint = paint2;
 } else {
  ltrInitRadius = radius2;
  rtlInitRadius = radius1;
  ltrPaint = paint2;
  rtlPaint = paint1;
 }
 float ltrX = getMeasuredWidth() / 2.0f - distance / 2.0f;
 ltrX = ltrX + (distance * fraction);//當前從左往右的球的X坐標
 float rtlX = getMeasuredWidth() / 2.0f + distance / 2.0f;
 rtlX = rtlX - (distance * fraction);//當前從右往左的球的X坐標
 //計算小球移動過程中的大小變化
 float ltrBallRadius, rtlBallRadius;
 if (fraction <= scaleStartFraction) { //動畫進度[0,scaleStartFraction]時,球大小由1倍逐漸縮放至ltrScale/rtlScale倍
  float scaleFraction = 1.0f / scaleStartFraction * fraction; //百分比轉(zhuǎn)換 [0,scaleStartFraction]] -> [0,1]
  ltrBallRadius = ltrInitRadius * (1 + (ltrScale - 1) * scaleFraction);
  rtlBallRadius = rtlInitRadius * (1 + (rtlScale - 1) * scaleFraction);
 } else if (fraction >= scaleEndFraction) { //動畫進度[scaleEndFraction,1],球大小由ltrScale/rtlScale倍逐漸恢復(fù)至1倍
  float scaleFraction = (fraction - 1) / (scaleEndFraction - 1); //百分比轉(zhuǎn)換,[scaleEndFraction,1] -> [1,0]
  ltrBallRadius = ltrInitRadius * (1 + (ltrScale - 1) * scaleFraction);
  rtlBallRadius = rtlInitRadius * (1 + (rtlScale - 1) * scaleFraction);
 } else { //動畫進度[scaleStartFraction,scaleEndFraction],球保持縮放后的大小
  ltrBallRadius = ltrInitRadius * ltrScale;
  rtlBallRadius = rtlInitRadius * rtlScale;
 }
 ltrPath.reset();
 ltrPath.addCircle(ltrX, centerY, ltrBallRadius, Path.Direction.CW);
 rtlPath.reset();
 rtlPath.addCircle(rtlX, centerY, rtlBallRadius, Path.Direction.CW);
 mixPath.op(ltrPath, rtlPath, Path.Op.INTERSECT);
 canvas.drawPath(ltrPath, ltrPaint);
 canvas.drawPath(rtlPath, rtlPaint);
 canvas.drawPath(mixPath, mixPaint);
 }

總結(jié)

以上所述是小編給大家介紹的Android中模仿抖音加載框之兩顆小球轉(zhuǎn)動控件效果,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

最新評論