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

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

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

1. 新建 path

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

 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 }

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

2.測量計算

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

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

 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 layout11      */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                     @Override22                     public void getOutline(View view, Outline outline) {23                         outline.setConvexPath(clipPath);24                     }25                 });26             }27         }28     }

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

3、繪制弧形

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

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

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

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

4、效果圖

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

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

 

問題

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

 

解決辦法

在網(wǎng)上查找了資料,也沒有發(fā)現(xiàn)什么好的辦法,最后在 Github 上面找到了答案 https://github.com/florent37/ArcLayout/issues/8。

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

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

 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     }

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

最終效果圖

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

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)