IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    造轮子:滚轮选择器实现及原理解析(三)

    bt发表于 2023-07-21 15:25:00
    love 0

    系列文章
    造轮子:滚轮选择器实现及原理解析(一)
    造轮子:滚轮选择器实现及原理解析(二)
    造轮子:滚轮选择器实现及原理解析(三)
    造轮子:滚轮选择器实现及原理解析(源码)

    上一节我们已经完成了基本的滚轮,且可以动起来了。
    这一篇我们完成更多的细节优化。

    循环滚动

    循环滚动的核心,在于如何处理中心item为0时,上面几个item的绘制
    前几篇我们见到了对y进行矫正的逻辑,使其不会小于0防止计算出错。
    那么这里我们同样可以对position下标进行矫正
    直接上代码

    protected void drawItem(Canvas canvas, int position, int centerPosition, float offsetY) {
        // 不循环显示时忽略超出边界的部分
        if (!isLoop && (position < 0 || position >= data.length)) {
            return;
        }
        ......
        String text = data[adjustingPosition(position)];
    }
    protected int adjustingPosition(int position) {
        int newPosition = position;
        while (newPosition < 0 || newPosition > data.length - 1) {
            if (newPosition < 0) {
                newPosition += data.length;
            } else {
                newPosition -= data.length;
            }
        }
        return newPosition;
    }

    优化滚轮视觉

    我们现在绘制的item的高度都是等高的,对于现在来说,甚至可以说我们现在仅仅画了一个listview出来
    但是市面上的滚轮,2端的文字明显显示的大小,透明度都要比中心的小,那么应该怎么做呢?

    1. 根据距离中心的position的差值设置alpha,字号等
    2. 实时计算距离设置alpha,缩放
      这里我采用了方案2,因为方案1在中心position发生变化时,会出现明显的抖动(字号从16瞬间变14能不抖吗?)
      2023-07-21T07:22:01.png
      我这里做了一个示意图,有2种方式可选择
    3. 先缩放再平移,那么平移的距离也会受到画布缩放的影响变得短,那么越靠近边缘,item之间的间距看起来越小
    4. 先平移再缩放,item之间的距离相同
      我这里使用了方法1,上代码
      protected void drawItem(Canvas canvas, int position, int centerPosition, float offsetY) {
       // 不循环显示时忽略超出边界的部分
       if (!isLoop && (position < 0 || position >= data.length)) {
           return;
       }
       String text = data[adjustingPosition(position)];
       float textWidth = paint.measureText(text);
       int count = centerPosition - position;
       float totalOffset = offsetY + count * itemHeight;
       float percent = 1f - Math.abs(totalOffset) / (itemHeight * showCount);
       canvas.save();
       // 先缩放后位移,可以使不同item的间距不同,距离中心越近间距越大
       canvas.scale(minScale + (1 - minScale) * percent, minScale + (1 - minScale) * percent, width / 2f, height / 2f);
       canvas.translate(0, -totalOffset);
       paint.setAlpha((int) (255 * (minAlpha + (1 - minAlpha) * percent)));
       Paint.FontMetrics metrics = paint.getFontMetrics();
       canvas.drawText(text, width / 2f - textWidth / 2f, height / 2f - (metrics.top + metrics.bottom) / 2f, paint);
       canvas.restore();
      }

    至此,滚轮选择器的功能已全部完成



沪ICP备19023445号-2号
友情链接