知是行的主意,行是知的功夫。这篇文章主要讲述Android使用Path实现仿最新淘宝轮播广告底部弧形有锯齿的问题以及解决办法相关的知识,希望能为你提供帮助。
在前面一篇博文《android高仿京东淘宝自动无限循环轮播控件的实现思路和过程》中已经基本介绍了实现轮播广告的基本思路和过程,但是仔细观察淘宝的轮播广告栏,发现在轮播广告栏的底部有个小小的弧形,为了实现更好的效果,在后期中在自己定义的无限轮播控件中添加了底部弧形的实现,在实现的过程中也遇到了一些问题,比较麻烦的就是绘制时弧形出现了锯齿的问题。
实现弧形的主要代码以及实现效果(带有锯齿的情况)
首先要感谢开源
感谢开源框架
https://github.com/florent37/ArcLayout ,弧形的实现效果是根据该框架而来,使用 path 来绘制弧形,首先就是要创建好 path 了。
1. 新建 path
1 private Path createClipPath() { 2final Path path = new Path(); 3path.moveTo(0, 0); 4path.lineTo(0, height); 5path.quadTo(width / 2, height - 2 * arcHeight, width, height); 6path.lineTo(width, 0); 7path.close(); 8 9return path; 10 }
2.测量计算
绘制弧形是根据轮播控件的宽度和高度而来的,所以需要先测量出轮播控件的宽度和高度,并且当子 View 的位置和尺寸变化时,需要重新测量绘制。
1 @Override 2protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 3super.onLayout(changed, left, top, right, bottom); 4if (changed) { 5calculateLayout(); 6} 7} 8 9/** 10*calculate layout 11*/ 12private void calculateLayout() { 13height = getMeasuredHeight(); 14width = getMeasuredWidth(); 15if (width > 0 & & height > 0) { 16 17clipPath = createClipPath(); 18if (Build.VERSION.SDK_INT > = Build.VERSION_CODES.LOLLIPOP & & arcShape != ArcShape.inSide) { 19setOutlineProvider(new ViewOutlineProvider() { 20@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 21@Override 22public void getOutline(View view, Outline outline) { 23outline.setConvexPath(clipPath); 24} 25}); 26} 27} 28}
3、绘制弧形
绘制图形时,有一个控件是很重要的,那就是 Canvas 画布,也是最后一步,在画布上面绘制。
1 @Override 2protected void dispatchDraw(Canvas canvas) { 3canvas.save(); 4 5canvas.clipPath(clipPath); 6super.dispatchDraw(canvas); 7 8canvas.restore(); 9}
4、效果图
运行代码,可以看到效果,效果图如下。
文章图片
问题
底部的弧形虽然已经绘制成功了,但是从效果图中可以明显看出弧形带有锯齿,效果并不好,再看下现在淘宝的效果,有点困扰了。
解决办法
在网上查找了资料,也没有发现什么好的办法,最后在 Github 上面找到了答案 https://github.com/florent37/ArcLayout/issues/8。
解决方法并不难,但是需要引入另外一个绘图工具 —— Paint,通过 Paint 来消除锯齿,因为 Paint 本身就有自带的消除锯齿的方法 paint.setAntiAlias(true),当然还需要设置下 Xfermode,不过和目前网上提供的方法有所不同了,看下面的代码,修改在画布 Canvas 中的绘制方法。
1 @Override 2protected void dispatchDraw(Canvas canvas) { 3Paint paint = new Paint(); 4paint.setAntiAlias(true); 5paint.setColor(Color.WHITE); 6int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG); 7super.dispatchDraw(canvas); 8paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY)); 9canvas.drawPath(clipPath, paint); 10canvas.restoreToCount(saveCount); 11paint.setXfermode(null); 12}
最终效果图
修改代码后运行,获得最终效果,已经明显消除了锯齿,效果优美多了,弧形变得光滑了。
文章图片
自定义的高仿京东淘宝控件已经修改完成了,代码已经开源在 Github 上面,https://github.com/LT5505/SliderLayout
【Android使用Path实现仿最新淘宝轮播广告底部弧形有锯齿的问题以及解决办法】
推荐阅读
- Android View 绘制流程(Draw) 完全解析
- Android 测试数据存储与访问XML解析与生成
- Android中应用程序获得系统权限
- Android中使用IntentService运行后台任务
- hellocharts-android-Android图表开源库的使用
- Android学习笔记--使用Universal-Image-Loaderf发生OOM到解决OOM问题
- 使用Kotlin开发Android应用
- callapplybind的异同
- Android USB转串口通信开发基本流程