Android自定义View实现滑块SeekBar

话不多说先上效果图:
效果
本篇文章实现上图的效果,主要使用canvas.drawPath()。

首先看到这张图想到的是直接画N个rect,有的实心有的空心不就完事了吗。不过这样的代码肯定是这样的

1
for(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,比较粗略,文笔也不好,就那这个简单的例子练练手。上源码:
点我下载