国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android自定義view Path 的高級用法之搜索按鈕動畫

2019-10-22 18:35:20
字體:
來源:轉載
供稿:網友

關于Path之前寫的也很多了,例如path繪制線,path繪制一階,二階和三階貝塞爾路徑,這些都是path的基本用法。今天我要帶大家看的是Path 的高級用法,先上圖,再吹。

android,自定義view,path搜索,按鈕動畫

效果大致是這樣的。看著是不是挺好。話不多說,切入正題:

既然今天要談Path的高級用法,那就先來講一講(Path -- 中文 )就是“路徑”既然是路徑,從我們面向對象的想法的話,我們就容易想到 路徑 的長度,路徑的某一點等。想到這里我們就引出今天 的主要 類--------PathMeasure,字面意思很容易理解--翻譯成 路徑測量。對這就是我們用來測量路徑的類。既然是一個類,我們就要看他集體有哪些方法和屬性。

1.構造方法:

一個是有參數,一個無參數。

無參數就很容易理解就是直接創建對象,那有參數呢?

PathMeasure(Path path, boolean forceClosed) ;第一個參數 Path  咿 !這不就是我們的Path 了嗎。對既然是測量類,那就是要確定需要測量的那個路徑,那第二個參數呢?

第二個參數是用來確保 Path 閉合,如果設置為 true, 則不論之前Path是否閉合,都會自動閉合該 Path(如果Path可以閉合的話)。

2.方法:

這方法還挺多,都是干啥的呢?就找幾個重要的,常用的講講:

第一個那就是 setPath(Path path, boolean forceClosed)

這方法一看就知道設置path 路徑的,就是如果我們創建 PathMeasure,時用的是無參的構造方法時 ,這時候就要用此方法,告訴PathMeasure 當前需要測量的是哪一個path路徑。(個人喜歡用無參,比較靈活)。

第二個那就是getLength(),很容易理解就是 獲得 path 的總長度。

第三個:getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo),這個方法非常重要,截取片段,截取的結果就是,我們的path路徑。參數也很好理解。第一個是開始的距離,第二個是結束的距離(相對于起點==既然是起點,我們怎么找他們的起點呢,其實就是我們繪制圖畫筆開始的哪一點)。第三個參數就是返回的路徑。第四個參數起始點是否使用 moveTo 用于保證截取的 Path 第一個點位置不變。

第四個:getPosTan(float distance, float[] pos, float[] tan),這個也是非常重要的,為什么呢?聽我解釋一下他的參數就知道了。第一個參數是距離(相對于繪制起點的路徑距離),第二個參數是距離起點的坐標點,第三個參數返回的是正玄函數tan@角度。

對這些參數了解之后下面就來講解我們今天的例子:

首先我們先來個簡單的:例如

android,自定義view,path搜索,按鈕動畫

如圖這樣的分析過程:

android,自定義view,path搜索,按鈕動畫

1.首先繪制一個圓(藍色的),從45度開始繪制,注意圓的起點。

2.同圓心繪制大圓(輔助圓)用來輔助繪制藍色的線。

3.通過getPosTan(float distance, float[] pos, float[] tan)方法得到兩個圓的終點的坐標。

4.利用lineTo(x,y)繪制線。就得到我們的搜索圖形了。

5.接下來就是實時 截取片段。getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo),截取從距離0到getlength();這樣就產生了一個動態的效果了。

看代碼:

關于畫筆,canvas畫布,valueanimator動畫,這些請看之前的博客,都有詳細講解。

public class MySearch extends View {  Paint paint;  Path searchPath; //搜索的圓  Path ciclePath; //外圓  //獲得寬高  int w;  int h;  //這是保存截取時,返回的坐標點  float serpos[];  float cicpos[];  //測量 path 的類  PathMeasure measure;  //動畫產生的實時數據  float value;  public MySearch(Context context) {    this(context,null);  }  public MySearch(Context context, @Nullable AttributeSet attrs) {    this(context,attrs,0);  }  public MySearch(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {    super(context, attrs, defStyleAttr);    //獲得屏幕的寬高    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);    w = wm.getDefaultDisplay().getWidth();    h = wm.getDefaultDisplay().getHeight();    //初始化數據    serpos = new float[2];    cicpos = new float[2];    //畫筆    paint = new Paint();    paint.setStyle(Paint.Style.STROKE);    paint.setDither(true);    paint.setStrokeWidth(6);    paint.setAntiAlias(true);    //初始化路徑    initPath();    //初始化動畫    initAnimator();  }  @Override  protected void onDraw(Canvas canvas) {    super.onDraw(canvas);    //移動畫布的遠點到屏幕中心    canvas.translate(w/2,h/5);    paint.setColor(Color.BLUE);    //這是截取方法返回的路徑    Path dra = new Path();    //解除硬件加速,不然沒效果    dra.reset();    dra.lineTo(0,0);    //設置當前需要測量的path    measure.setPath(searchPath,false);    //開始截取    boolean s = measure.getSegment(measure.getLength()*value,measure.getLength(),dra,true);    //繪制路徑    canvas.drawPath(dra,paint);  }  /**   * 初始化路徑   */  public void initPath(){    paint.setColor(Color.BLUE);    //搜索的圓    searchPath = new Path();    RectF rectF = new RectF(-50,-50,50,50);    searchPath.addArc(rectF,45,359.9f);    //輔助圓    ciclePath = new Path();    RectF rectF1 = new RectF(-100,-100,100,100);    ciclePath.addArc(rectF1,45,359.9f);    //測量類    measure = new PathMeasure();    measure.setPath(searchPath,false);    //獲取坐標    measure.getPosTan(0,serpos,null);    measure.setPath(ciclePath,false);    //獲取坐標    measure.getPosTan(0,cicpos,null);    //根據兩點坐標繪制線    searchPath.lineTo(cicpos[0],cicpos[1]);  }  /**   * 初始化動畫   */  public void initAnimator(){    ValueAnimator animator = ValueAnimator.ofFloat(0,1);    animator.setDuration(2600);    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {      @Override      public void onAnimationUpdate(ValueAnimator animation) {        value = (float) animation.getAnimatedValue();        postInvalidate();      }    });    animator.start();  }}

第一個圖大家學會了,去練習一下吧!


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 象州县| 安国市| 游戏| 汕头市| 恩平市| 太和县| 宜宾市| 泸州市| 施甸县| 崇左市| 崇义县| 博客| 清远市| 富阳市| 民丰县| 广东省| 迭部县| 长葛市| 金塔县| 南安市| 万山特区| 来宾市| 青冈县| 新龙县| 台南县| 湖口县| 杭锦旗| 襄汾县| 扎鲁特旗| 盈江县| 武穴市| 安阳县| 新巴尔虎右旗| 宝兴县| 西藏| 遵化市| 仙游县| 城口县| 疏勒县| 化州市| 乡宁县|