Android自定义View实现滑块SeekBar
话不多说先上效果图:
本篇文章实现上图的效果,主要使用canvas.drawPath()。
首先看到这张图想到的是直接画N个rect,有的实心有的空心不就完事了吗。不过这样的代码肯定是这样的
1for(int i=0;;i++) canvas.drawRect();
乍看觉得没问题啊,但canvas不断的重复调用drawXX的方式好吗?有没更好的方式,那么我们的Path登场了。
把需要绘制的rect合并到Path中然后交给canvas一次处理就好了。
好了这么一说其实很简单了,
核心计算path的算法如下:
for (int i = 0; i < mBlockCount; i++) {
float left = getPaddingLeft() + (mBlockWidth + mBlockSpace) * i;
float right = left + mBlockWidth;
float bottom = top + height;
Path outsidePath = new Path();
RectF outsideRect = new RectF(left, top, right, bottom);
outsidePath.addRoundRect(outsideRect, mBlockRadius, mBlockRadius,
Path.Direction.CW);
Path insidePath = new Path();
RectF insidedeRect = new RectF(left + mBlockLineWidth,
top + mBlockLineWidth, right - mBlockLineWidth,
bottom - mBlockLineWidth);
insidePath.addRoundRect(insidedeRect, mBlockRadius,
mBlockRadius, Path.Direction.CW);
mInsidePaths.add(insidePath);
mOutsidePaths.add(outsidePath);
}
我们把滑块分为内层的rect一组跟外层的rect一组,算出2组path备用。然后开启我们的draw之旅:
Draw
我们有了内外层的path了怎么用呢。直接draw,好像这样绘制出来的是两个重叠的区域吧。莫慌canvas里面本身还提供了canvas.clipPath的方法:
for (int i = 0; i < mBlockCount; i++) {
if (i >= _curblock) { //_curblock表示当前的滑块值
canvas.clipPath(mInsidePaths.get(i), Op.DIFFERENCE);
}
canvas.drawPath(mOutsidePaths.get(i), mPaint);
}
好了到这里差不多了然后再添加一些自定义属性,因为我们的滑动是分垂直跟水平方向的,这边属性公用了 android:orientation
attrs
- android:orientation
- point_progress
- point_max
- point_small_radius
- point_block_radius
- point_progress_height
- point_progress_full_color
- point_progress_empty_color
- point_border_line_color
- point_border_fill_color
- point_border_line_width
End
好了最后觉得应该显示一下滑块的值,那么利用canvas.drawText轻松搞定了。
初次尝试写blog,比较粗略,文笔也不好,就那这个简单的例子练练手。上源码:
点我下载