a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 系統(tǒng) > Android > 正文

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

2019-12-12 00:32:15
字體:
供稿:網(wǎng)友

安卓版抖音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方法 默認(rèn)值
球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
動畫進(jìn)度在[0,scaleStartFraction]期間,小球大小逐漸縮放 scaleStartFraction setStartEndFraction() 0.2f
動畫進(jìn)度在[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;那么實(shí)際效果就是一顆小球從左邊開始向右移動

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

實(shí)現(xiàn)思路

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

   

 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里重啟動畫,以此實(shí)現(xiàn)每一次移動后小球能停頓一定時間。在onAnimationUpdate里,我們記錄了當(dāng)前動畫百分比fraction,然后通過invalidate()重繪,在之后的onDraw里將通過該值畫出小球。另外,每次動畫開始時(或是重復(fù)時),會將isLtr取反,這個標(biāo)志位的作用是標(biāo)明當(dāng)前哪顆球在【從左往右】移動,因?yàn)閮深w球的顏色、初始半徑是不一樣的嘛,onDraw里畫小球時是需要這個標(biāo)志位協(xié)助的。

有了動畫進(jìn)度fraction和標(biāo)志位isLtr后,就可以在onDraw里畫出小球了。

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

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

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

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

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

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

xfermode

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

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

op

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

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

onDraw完整代碼:

@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); float centerY = getMeasuredHeight() / 2.0f; float ltrInitRadius, rtlInitRadius; Paint ltrPaint, rtlPaint; //確定當(dāng)前【從左往右】移動的是哪顆小球 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);//當(dāng)前從左往右的球的X坐標(biāo) float rtlX = getMeasuredWidth() / 2.0f + distance / 2.0f; rtlX = rtlX - (distance * fraction);//當(dāng)前從右往左的球的X坐標(biāo) //計(jì)算小球移動過程中的大小變化 float ltrBallRadius, rtlBallRadius; if (fraction <= scaleStartFraction) { //動畫進(jìn)度[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) { //動畫進(jìn)度[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 { //動畫進(jìn)度[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)網(wǎng)站的支持!

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 色图综合 | 国产精品theporn | 亚洲va一区二区 | 中文字幕一区二区三区精彩视频 | 久久精品亚洲 | 日韩视频一区二区三区四区 | 99爱视频在线观看 | 99精品99| 日韩一二区 | 日韩欧美手机在线 | 影院av| 国产精品免费一区二区三区都可以 | 毛片在线视频 | 日韩三区在线观看 | 国产一区二区三区久久久 | 国产一区| 伊人免费视频 | av第一页| 毛片免费看 | 羞羞小视频在线观看 | 国产精品久久久久久久久久久久冷 | 亚洲视频一| 国产精品久久久久久久一区探花 | 亚洲国产一区视频 | 亚洲欧美日韩另类精品一区二区三区 | 久久久国产一区 | 免费毛片在线播放 | 精品亚洲永久免费精品 | 日本黄色免费 | 欧美一级在线视频 | 午夜电影合集 | 国产小视频在线观看 | av片免费| 亚洲伊人久久网 | 日本久久二区 | 欧美日韩精品一区二区在线播放 | 国产精品一区在线看 | 欧美日韩亚洲另类 | 精品国产99 | 欧美性猛交一区二区三区精品 | 久久国产成人午夜av影院宅 |