• 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

  • 相关阅读:
    神兽保佑-代码无BUG
    HDU 1022 Train Problem I (数据结构 —— 栈)
    iOS开发
    漫谈程序猿系列:无BUG不生活
    王立平--Unity破解
    java远程调用rmi入门实例
    高仿美团iOS版,版本5.7
    JAVA日志系统
    读《互联网创业password》之随想
    解决iOS空指针数据的问题
  • 原文地址:https://www.cnblogs.com/LT5505/p/6689273.html
Copyright © 2020-2023  润新知