-
好久沒寫博客了,關於自定義view之前也寫過很多,今天就來對自定義view做個總結,在自定義view中需要掌握哪些知識呢!在討論之前首先來看看今天的demo效果
-
-
效果還是挺炫酷的,寫這個例子的原因也是我看到網上別人寫的一個效果,感覺不錯就拿來模仿了一下。其實每個view實現的方法有很多種,根據自己的自定義view的知識量來寫,實現方式可能都不相同,所以大家當看到比較炫酷的view的時候可以嘗試去試一試,如果有些效果實現不了,可以去看看別人的思想。“寫”也是一個“學”的過程。多了不扯,先來總結一下自定義view的知識點(如有遺漏大家下面補充):
-
1.首先自定義view的構造方法的寫法,自定義屬性,view的測量onMusure(),ondraw()這些就不多說了,這是必須掌握的。
-
2.既然要畫圖自然少不了;Paint畫筆這個類,paint的相關方法你是否熟練,不熟悉的趕快去看看。
-
3.canvas 畫布,開玩笑有畫筆哪能少了畫布。
-
4.Path路徑這個牛逼了,要想實現比較酷酷的畫面還真是不能少了他,二階貝塞爾曲線和三階貝塞爾曲線,這個還需要好好研究研究。
-
5.有了Path 我們自然會想到他的兄弟那就是 PathMesure ,爲什麼說是他兄弟,有了路徑我們是不是要知道路徑的長度,每個點的座標,角度,沒錯PathMesure就是對Path進行測量的,這個類我之前博客裏都有講過。
-
6.有了這些是不是就夠了呢?那可能我們的自定義view是個“殘廢”,爲什麼?因爲他動不了,怎麼讓他動起來呢?那就是需要動畫的參與了兩個重要的動畫類;ValueAnimator和ObjectAnimator 我們自定義view基本這兩個動畫足夠用了,當然動畫最重要的最難的還是自定義插值器,有些特殊的需求view移動的時候,可以自己定義速度已經點座標。
-
7.有了這些基本你就能做出很懸的效果了,但是還有一個很重要的類;PorterDuffXfermode 恩恩這個也很重要,弄清楚他的16/18個圖形展示的效果。
-
基本這些......應該就差不多了....夜深了,想不出來了,少的大家給個補充...............還有一個很重要的是要大膽去嘗試,哪怕弄了一半搞不動了。。。
-
-
扯了半天,下面就來看看我們的這個綜合的demo,涉及到的知識點還是比較多得。
-
首先我們先來分析一下這個動畫的過程,大致分爲三個過程:
-
1.是大圓被小圓吞噬的過程(PorterDuffXfermode ),主要我們的矩形是不能被覆蓋的。
-
2.是大圓被吞噬完之後我們處理圓環的繪製,這個圓環採用的是三階貝塞爾曲線(path),圓環變成直線的過程,以及回彈效果。
-
3.矩形被彈飛的過程(爲了方便這裏我直接用的動畫,其實更好的做法是先給矩形設置一個拋物線狀的移動的path路徑)。
-
大致分爲這幾個過程,下面就一一說明:
-
過程一:是大圓被小圓吞噬的過程。這裏就比較簡單繪製兩個圓,利用PorterDuffXfermode顯示,
-
首先定義一個對象
-
PorterDuffXfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
private void drawCicle(Canvas canvas) { int lay = canvas.saveLayer(-r,-r,r,r,paint,Canvas.ALL_SAVE_FLAG); paint.setColor(Color.parseColor("#944B1E2E")); canvas.drawCircle(0,0,r,paint); paint.setXfermode(xfermode); paint.setColor(Color.parseColor("#FF4081")); canvas.drawCircle(0,0,xr,paint); paint.setXfermode(null); canvas.restoreToCount(lay); if (isfirstCicle) { cicleAnimation(); isfirstCicle = false; } }
private void bounceLine(Canvas canvas) { path1.moveTo(0,r-r_b); path1.cubicTo(67,r-r_b,67,-r+r_bounce,0+r_bounce*4,-r+r_bounce); path1.moveTo(0-r_bounce*4,-r+r_bounce); path1.cubicTo(-67,-r+r_bounce,-67,r-r_b,0,r-r_b); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(2); paint.setColor(Color.BLACK); canvas.drawPath(path1,paint); path1.reset(); if (isfirstBounce) { bounceAnimation(); isfirstBounce = false; } }
RectF f = new RectF(-10-rect_position_x,-10-rect_position_y,10-rect_position_x,10-rect_position_y);
float rect_position_y = 0; float rect_position_x = 0; private void rectAnimation() { ValueAnimator a = ValueAnimator.ofFloat(0,120,30); a.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { rect_position_y = (float) animation.getAnimatedValue(); invalidate(); } }); a.setDuration(800); a.setInterpolator(new AccelerateDecelerateInterpolator()); ValueAnimator v = ValueAnimator.ofFloat(0,4*r); v.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { rect_position_x = (float) animation.getAnimatedValue(); invalidate(); } }); v.setDuration(800); v.setInterpolator(new AccelerateDecelerateInterpolator()); a.start(); v.start(); }