Android使用Path實現仿最新淘寶輪播廣告底部弧形有鋸齒的問題以及解決辦法


在前面一篇博文《Android高仿京東淘寶自動無限循環輪播控件的實現思路和過程》中已經基本介紹了實現輪播廣告的基本思路和過程,但是仔細觀察淘寶的輪播廣告欄,發現在輪播廣告欄的底部有個小小的弧形,為了實現更好的效果,在后期中在自己定義的無限輪播控件中添加了底部弧形的實現,在實現的過程中也遇到了一些問題,比較麻煩的就是繪制時弧形出現了鋸齒的問題。

實現弧形的主要代碼以及實現效果(帶有鋸齒的情況)

首先要感謝開源 感謝開源框架 https://github.com/florent37/ArcLayout ,弧形的實現效果是根據該框架而來,使用 path 來繪制弧形,首先就是要創建好 path 了。

1. 新建 path

 1 private Path createClipPath() {
 2         final Path path = new Path();
 3         path.moveTo(0, 0);
 4         path.lineTo(0, height);
 5         path.quadTo(width / 2, height - 2 * arcHeight, width, height);
 6         path.lineTo(width, 0);
 7         path.close();
 8         
 9         return path;
10 }

2.測量計算

繪制弧形是根據輪播控件的寬度和高度而來的,所以需要先測量出輪播控件的寬度和高度,並且當子 View 的位置和尺寸變化時,需要重新測量繪制。

 1 @Override
 2     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
 3         super.onLayout(changed, left, top, right, bottom);
 4         if (changed) {
 5             calculateLayout();
 6         }
 7     }
 8 
 9     /**
10      *calculate layout
11      */
12     private void calculateLayout() {
13         height = getMeasuredHeight();
14         width = getMeasuredWidth();
15         if (width > 0 && height > 0) {
16 
17             clipPath = createClipPath();
18             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && arcShape != ArcShape.inSide) {
19                 setOutlineProvider(new ViewOutlineProvider() {
20                     @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
21                     @Override
22                     public void getOutline(View view, Outline outline) {
23                         outline.setConvexPath(clipPath);
24                     }
25                 });
26             }
27         }
28     }

3、繪制弧形

繪制圖形時,有一個控件是很重要的,那就是 Canvas 畫布,也是最后一步,在畫布上面繪制。

1 @Override
2     protected void dispatchDraw(Canvas canvas) {
3         canvas.save();
4 
5         canvas.clipPath(clipPath);
6         super.dispatchDraw(canvas);
7 
8         canvas.restore();
9     }

4、效果圖

運行代碼,可以看到效果,效果圖如下。

 

問題

底部的弧形雖然已經繪制成功了,但是從效果圖中可以明顯看出弧形帶有鋸齒,效果並不好,再看下現在淘寶的效果,有點困擾了。

 

解決辦法

在網上查找了資料,也沒有發現什么好的辦法,最后在 Github 上面找到了答案 https://github.com/florent37/ArcLayout/issues/8。

解決方法並不難,但是需要引入另外一個繪圖工具 —— Paint,通過 Paint 來消除鋸齒,因為 Paint 本身就有自帶的消除鋸齒的方法 paint.setAntiAlias(true),當然還需要設置下 Xfermode,不過和目前網上提供的方法有所不同了,看下面的代碼,修改在畫布 Canvas 中的繪制方法。

 1 @Override
 2     protected void dispatchDraw(Canvas canvas) {
 3         Paint paint = new Paint();
 4         paint.setAntiAlias(true);
 5         paint.setColor(Color.WHITE);
 6         int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
 7         super.dispatchDraw(canvas);
 8         paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
 9         canvas.drawPath(clipPath, paint);
10         canvas.restoreToCount(saveCount);
11         paint.setXfermode(null);
12     }

最終效果圖

修改代碼后運行,獲得最終效果,已經明顯消除了鋸齒,效果優美多了,弧形變得光滑了。

 

 

自定義的高仿京東淘寶控件已經修改完成了,代碼已經開源在 Github 上面,https://github.com/LT5505/SliderLayout

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM