系列文章
造轮子:滚轮选择器实现及原理解析(一)
造轮子:滚轮选择器实现及原理解析(二)
造轮子:滚轮选择器实现及原理解析(三)
造轮子:滚轮选择器实现及原理解析(源码)
上一节我们已经完成了基本的滚轮,且可以动起来了。
这一篇我们完成更多的细节优化。
循环滚动的核心,在于如何处理中心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端的文字明显显示的大小,透明度都要比中心的小,那么应该怎么做呢?
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();
}
至此,滚轮选择器的功能已全部完成