亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在Android中實現一個水滴效果

發布時間:2021-04-20 17:10:50 來源:億速云 閱讀:438 作者:Leah 欄目:移動開發

這期內容當中小編將會給大家帶來有關怎么在Android中實現一個水滴效果,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

Android是什么

Android是一種基于Linux內核的自由及開放源代碼的操作系統,主要使用于移動設備,如智能手機和平板電腦,由美國Google公司和開放手機聯盟領導及開發。

一、總體思路

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;

上述就是小編為大家分享的怎么在Android中實現一個水滴效果了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

崇礼县| 赤峰市| 留坝县| 涟水县| 甘孜县| 泰和县| 罗源县| 襄汾县| 富蕴县| 营山县| 武乡县| 嘉黎县| 额尔古纳市| 灯塔市| 贵定县| 镇巴县| 土默特左旗| 乌拉特后旗| 鹤庆县| 鄯善县| 富平县| 称多县| 定结县| 比如县| 恩施市| 康定县| 青神县| 吉首市| 怀远县| 白城市| 宝山区| 西乌| 山阳县| 通山县| 德安县| 兴化市| 抚宁县| 崇左市| 抚顺市| 思南县| 阿拉善左旗|