亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > Android > 正文

Android控件實現水滴效果

2019-10-21 21:25:02
字體:
來源:轉載
供稿:網友

看到ios版上QQ刷新效果像水滴,然后自己也想著去實現這樣的效果,這篇文章暫時沒有介紹下拉刷新的效果,只是單獨用一個控件來實現這樣的水滴效果。

效果圖如下:

Android控件,水滴

一、總體思路

1、畫兩個圓形,其中一個就是上面的大圓,還有一個是下面的小圓,大圓和小圓不斷變小,大圓的位置保持不變,小圓的位置不斷向下移動,即圓心不斷下移。 
2、畫兩邊的曲線,這時候用到貝塞爾曲線去畫。 
3、用屬性動畫實現動態的效果。

二、代碼實現

1、找出畫曲線的幾個關鍵點。

Android控件,水滴Android控件,水滴

其實我是在第一張圖的基礎上,再在上面分別畫兩個圓,就可以得到第二張圖了。關鍵是畫出第一張圖。

(1)在這里,p1,p2,p3,p4,這4個點分別對應兩個圓的兩邊的點,即p1到p2就是圓的直徑。p3和p4同理,那么就很容易確定這四個點的坐標了。

(2)然后c1和c2是分別控制p1到p3、p2到p4的曲線,是貝塞爾曲線的控制點。它們的橫坐標對應的是p3,p4的橫坐標(相等),縱坐標取兩個圓心距離的一半。這樣畫出這個靜態的圖片就不難了。

(3)畫上下兩個圓進去,就會變成第二張圖的效果。

2、在構造方法中調用init()初始化一些基本的變量

private void init(Context context, AttributeSet attrs) {    drawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG        | Paint.FILTER_BITMAP_FLAG);    paint = new Paint();    paint.setColor(fillColor);    // 轉換為像素單位    bigRadius = dip2px(context, bigRadius);    smallRadius = dip2px(context, smallRadius);    distance = dip2px(context, distance);  }

3、在onDraw()方法中畫水滴效果

要注意的是path需要重新new, 貝塞爾曲線的繪制,用到是path.quadTo這方法。具體可以看代碼。

@Override  protected void onDraw(Canvas canvas) {    // 必須重新new,不然路徑會重復,我之前就是這樣    path = new Path();    // 把畫布移到中心    canvas.translate(width / 2, height / 2);    // 從canvas層面去除繪制時鋸齒    canvas.setDrawFilter(drawFilter);    // 當前的兩個圓心的距離    currentDis = distance * fraction;    // 計算當前大圓的半徑    float bigRadius = this.bigRadius - currentDis / bigPercent;    float smallRadius = 0;    if (currentDis > 5) {// 距離大于5才改變小圓的半徑      smallRadius = this.smallRadius - currentDis / smallPercent;    }    // 大圓兩邊的兩個點坐標    leftX = -bigRadius;// 大圓當前的半徑    leftY = rightY = 0;    rightX = bigRadius;// 大圓當前的半徑    // 小圓兩邊的兩個點坐標    leftX2 = -smallRadius;// 小圓當前的半徑    leftY2 = rightY2 = currentDis;    rightX2 = -leftX2; // 小圓當前的半徑    // 兩個控制點    controlX1 = -smallRadius;// x坐標取小圓當前的半徑大小    controlY1 = currentDis / 2;// y坐標取兩個圓距離的一半    controlX2 = smallRadius;// x坐標取小圓當前的半徑大小    controlY2 = currentDis / 2;// y坐標取兩個圓距離的一半    path.moveTo(leftX, leftY);    path.lineTo(rightX, rightY);    // 用二階貝塞爾曲線畫右邊的曲線,參數的第一個點是右邊的一個控制點    path.quadTo(controlX2, controlY2, rightX2, rightY2);    path.lineTo(leftX2, leftY2);    // 用二階貝塞爾曲線畫左邊邊的曲線,參數的第一個點是左邊的一個控制點    path.quadTo(controlX1, controlY1, leftX, leftY);    // 畫大圓    canvas.drawCircle(0, 0, bigRadius, paint);    // 畫小圓    canvas.drawCircle(0, currentDis, smallRadius, paint);    // 畫path    canvas.drawPath(path, paint);  }

4、用屬性動畫,實現動態的效果。

/*** 執行屬性動畫,實現水滴的效果 */  public void perforAnim() {    ValueAnimator valAnimator = ObjectAnimator.ofFloat(0, 1);    valAnimator.addUpdateListener(new AnimatorUpdateListener() {      @Override      public void onAnimationUpdate(ValueAnimator animation) {        fraction = (float) animation.getAnimatedValue();        postInvalidate();      }    });    valAnimator.setDuration(duration);    valAnimator.start();  }

5、重寫onMeasure()方法,處理wrap_content情況。

@Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    super.onMeasure(widthMeasureSpec, heightMeasureSpec);    /*     * 處理為wrap_content情況,那么它的specMode是AT_MOST模式,在這種模式下它的寬/高     * 等于spectSize,這種情況下view的spectSize是parentSize,而parentSize是     * 父容器目前可以使用大小,就是父容器當前剩余的空間大小, 就相當于使用match_parent一樣 的效果,因此我們可以設置一個默認的值     */    int widthSpectMode = MeasureSpec.getMode(widthMeasureSpec);    int widthSpectSize = MeasureSpec.getSize(widthMeasureSpec);    int heightSpectMode = MeasureSpec.getMode(heightMeasureSpec);    int heightSpectSize = MeasureSpec.getSize(heightMeasureSpec);    if (widthSpectMode == MeasureSpec.AT_MOST        && heightSpectMode == MeasureSpec.AT_MOST) {      setMeasuredDimension(width, height);    } else if (widthSpectMode == MeasureSpec.AT_MOST) {      setMeasuredDimension(width, heightSpectSize);    } else if (heightSpectMode == MeasureSpec.AT_MOST) {      setMeasuredDimension(widthSpectSize, height);    }  }

6、其它的一些方法實現。

@Override  protected void onLayout(boolean changed, int left, int top, int right,      int bottom) {    super.onLayout(changed, left, top, right, bottom);    if (changed) {      width = right - left;      height = bottom - top;    }  }  /**   * 根據手機的分辨率從 dp 的單位 轉成為 px(像素)   */  public int dip2px(Context context, float dpValue) {    final float scale = context.getResources().getDisplayMetrics().density;    return (int) (dpValue * scale + 0.5f);  }

7、字段的定義

private final int fillColor = 0xff999999;// 填充顏色 private Paint paint; private int width = 100, height = 300;// 默認寬高 /* 兩個圓心的最大距離 / private int distance = 60; /* 當前兩個圓心的距離 / private float currentDis = 0; private float bigRadius = 20;// 大圓半徑 private float smallRadius = 10;// 小圓半徑 private float controlX1, controlX2, controlY1, controlY2;// 兩個控制點的坐標 private float leftX, leftY, rightX, rightY;// 大圓兩邊的兩個點的坐標 private float leftX2, leftY2, rightX2, rightY2; // 小圓兩邊的兩個坐標 DrawFilter drawFilter; Path path; /* 由屬性動畫控制,范圍為0-1 */ float fraction = 0;// 比例值 /* 大圓半徑變化的比例 / private final int bigPercent = 8; /* 小圓半徑變化的比例 / private final int smallPercent = 20; // 動畫的執行時間 private long duration = 3000;

三、總結

一種動畫效果,應該先分析它的靜態的實現,然后添加動態的效果,這樣就比較容易實現它的動畫效果了。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91夜夜揉人人捏人人添红杏| 欧美一区二区三区免费视| 亚洲3p在线观看| 欧美日韩成人网| 精品久久香蕉国产线看观看亚洲| 中文字幕视频一区二区在线有码| 亚洲高清免费观看高清完整版| 97在线精品国自产拍中文| 亚洲国产精品99| 国内精品久久久久| 亚洲xxxx18| 欧美国产亚洲视频| 欧美尺度大的性做爰视频| 91亚洲精华国产精华| 国产精品视频白浆免费视频| 欧美日韩一区二区三区在线免费观看| 欧美激情videoshd| 国产精品视频xxxx| 色婷婷亚洲mv天堂mv在影片| 久久精品成人欧美大片古装| 久久久亚洲欧洲日产国码aⅴ| 亚洲美女av网站| 一区二区亚洲欧洲国产日韩| 亚洲日韩欧美视频| 成人久久久久爱| 欧美人与性动交a欧美精品| 亚洲国产天堂久久国产91| 久久精品成人动漫| 国产午夜精品一区二区三区| 69久久夜色精品国产7777| 亚洲伦理中文字幕| 午夜精品一区二区三区在线播放| 国产精品久久久久久久久久新婚| 日韩一区二区三区国产| 中文字幕少妇一区二区三区| 欧美小视频在线| 国产日韩中文字幕| 成人欧美一区二区三区黑人孕妇| 亚洲国产精品成人va在线观看| 欧美激情成人在线视频| 国产精品jizz在线观看麻豆| 国产精品wwwwww| 久久久国产精品x99av| 欧美性猛交xxxx黑人猛交| 欧美日韩爱爱视频| 美女撒尿一区二区三区| www.亚洲一二| 欧美精品免费看| 久久国产精品久久精品| 久久大大胆人体| 狠狠躁夜夜躁人人爽天天天天97| 中文字幕欧美国内| 精品亚洲国产视频| 亚洲精品少妇网址| 国产精品美女久久久久久免费| 欧美性生交大片免网| 日韩毛片中文字幕| 欧美一级视频免费在线观看| 法国裸体一区二区| 日韩在线观看电影| 久久91精品国产| 亚洲成人激情在线观看| 国产91露脸中文字幕在线| 亚洲成色777777在线观看影院| 欧美性猛交视频| www.日韩不卡电影av| 欧美精品在线第一页| 欧美日韩国产中文字幕| 亚洲xxxxx| 亚洲福利视频二区| 国产精品999999| 国产噜噜噜噜久久久久久久久| 午夜精品一区二区三区在线视频| 亚洲在线www| 另类图片亚洲另类| 色综合色综合网色综合| 日本国产高清不卡| 亚洲专区在线视频| 91国偷自产一区二区三区的观看方式| 欧美激情视频一区| 久久电影一区二区| 日韩中文字幕在线观看| 亚洲aa中文字幕| 日韩高清欧美高清| 欧美高跟鞋交xxxxxhd| 久久久久这里只有精品| 成人黄色网免费| 亚洲奶大毛多的老太婆| 91黑丝在线观看| 久久91亚洲精品中文字幕奶水| 亚洲综合大片69999| 国产欧美 在线欧美| 日韩高清av在线| 俺也去精品视频在线观看| 国产精品久久久久999| 激情亚洲一区二区三区四区| 亚洲视频一区二区| 97人人做人人爱| 一夜七次郎国产精品亚洲| 国产日韩在线亚洲字幕中文| 亚洲大胆人体在线| 欧美专区日韩视频| 欧美一级片在线播放| 国产精品久久久久久久久久久久| 亚洲最大的成人网| 欧美中文字幕在线观看| 亚洲大胆人体视频| 欧美激情一区二区三区久久久| 亚洲精品视频在线播放| 亚洲国产成人精品一区二区| 国产精品爱久久久久久久| 欧美日韩精品在线视频| 精品久久久中文| 日韩av在线网| 欧美极品少妇xxxxⅹ裸体艺术| 国产精品日韩久久久久| 久久久91精品国产| 欧美激情奇米色| 日韩欧美在线观看视频| 78m国产成人精品视频| 国产精品大陆在线观看| 欧美日韩一区二区三区| 日韩福利伦理影院免费| 91久久久久久久一区二区| 国内精品模特av私拍在线观看| 91精品国产99久久久久久| 亚洲跨种族黑人xxx| 国产成人久久久| 欧美一级淫片播放口| 欧美日韩国产一区中文午夜| 青青精品视频播放| 国产精品一区二区三区久久| 国模精品视频一区二区三区| 亚洲成人精品av| 国产精品成人aaaaa网站| 亚洲国产成人精品久久| 欧美激情免费观看| 亚洲free性xxxx护士白浆| 一区二区三区亚洲| 国产精品三级美女白浆呻吟| 中文字幕无线精品亚洲乱码一区| 日韩视频免费在线| 国产成人精品午夜| 久久久国产成人精品| 亚洲黄色在线看| 欧美劲爆第一页| 欧美久久精品一级黑人c片| 成人欧美一区二区三区黑人| 日韩av成人在线观看| 亚洲电影免费观看高清完整版在线观看| 欧美美女18p| 亚洲精品综合久久中文字幕| 岛国视频午夜一区免费在线观看| 亚洲精品免费一区二区三区| 国产精品美女久久| 麻豆一区二区在线观看| 成人精品福利视频| 欧美日韩成人精品| 亚洲人午夜色婷婷| 美女精品视频一区| 91亚洲国产成人久久精品网站| 精品自拍视频在线观看| 国产精品亚发布| 亚洲老司机av|