Android 绘制虚线<XML><自定义view中onDraw绘制>

水平虚线

如果需要完成上面的水平虚线,可以这样处理。

  • 声明shape,其中dashGap是虚线的间隔宽度,dashWidth是实线的间隔宽度,stroke翻译过来是名词,画
 
 
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <shape xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:shape="line" >
  4. <stroke
  5. android:width="1dp"
  6. android:dashGap="3dp"
  7. android:dashWidth="3dp"
  8. android:color="#ffececec" />
  9. <size android:height="1dp"/>
  10. </shape>
  • 然后可以在layout文件中直接使用
 
 
  1. <View
  2. android:layout_width="match_parent"
  3. android:layout_height="2dp"
  4. android:contentDescription="@string/contentDescription"
  5. android:layerType="software"
  6. android:background="@drawable/dash_line" />

竖直虚线

按照上面的实现思路,把水平线直接转换为竖直线就可以,实现上并没有什么难点

 
 
  1. <View
  2. android:layout_width="2dp"
  3. android:layout_height="match_parent"
  4. android:contentDescription="@string/contentDescription"
  5. android:layerType="software"
  6. android:background="@drawable/dash_line" />

然后运行,你会很惊讶的发现,居然啥也显示不出来,这是弄啥咧?然后慌张的打开Stack Overflow,然后惊奇的发现,竖直虚线需要在水平虚线基础上旋转90

 
 
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
  3. <item
  4. android:left="-300dp"
  5. android:right="-300dp">
  6. <rotate
  7. android:drawable="@drawable/dash_line"
  8. android:fromDegrees="90"
  9. android:toDegrees="90"
  10. android:visible="true" />
  11. </item>
  12. </layer-list>

shape准备好以后,直接拿过来使用即可

 
 
  1. <View
  2. android:layout_width="4dp"
  3. android:layout_height="match_parent"
  4. android:layout_marginBottom="5dp"
  5. android:layout_marginTop="5dp"
  6. android:background="@drawable/dash_vertical_line"
  7. android:contentDescription="@string/app_name"
  8. android:layerType="software" />

这样很轻松就把水平虚线转换成了竖直虚线,但是上面的实现方式会遇到如下问题:

在小米1S真机上显示不出来,原因是不支持LAYER_TYPE_SOFTWARE

解决方案

针对上面的问题,可以通过最原始的canvas画线来解决,因为代码比较简单,这里直接给出code即可。

自定义DashView实现

 
 
  1. public class VerticalDashView extends View {
  2. private Paint mDashPaint;
  3. private Rect mRect;
  4. public VerticalDashView(Context context, AttributeSet attrs) {
  5. super(context, attrs);
  6. init();
  7. }
  8. @SuppressLint({ "InlinedApi", "NewApi" })
  9. private void init() {
  10. if (Build.VERSION.SDK_INT >= 11) {
  11. setLayerType(View.LAYER_TYPE_SOFTWARE, null);
  12. }
  13. final DisplayMetrics metrics = getResources().getDisplayMetrics();
  14. float width = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, metrics);
  15. float dashGap = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, metrics);
  16. float dashWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, metrics);
  17. mDashPaint = new Paint();
  18. mDashPaint.setColor(0xffececec);
  19. mDashPaint.setStyle(Style.STROKE);
  20. mDashPaint.setStrokeWidth(width);
  21. mDashPaint.setAntiAlias(true);
  22. //DashPathEffect是Android提供的虚线样式API,具体的使用可以参考下面的介绍
  23. mDashPaint.setPathEffect(new DashPathEffect(new float[] { dashWidth, dashGap }, 0));
  24. mRect = new Rect();
  25. }
  26. @Override
  27. protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
  28. super.onLayout(changed, left, top, right, bottom);
  29. //取出线条的位置(位置的定义放在XML的layout中,具体如下xml文件所示)
  30. mRect.left = left;
  31. mRect.top = top;
  32. mRect.right = right;
  33. mRect.bottom = bottom;
  34. }
  35. @Override
  36. protected void onDraw(Canvas canvas) {
  37. float x0 = (mRect.right - mRect.left) / 2f;
  38. float y0 = 0;
  39. float x1 = x0;
  40. float y1 = y0 + mRect.bottom - mRect.top;
  41. canvas.drawLine(x0, y0, x1, y1, mDashPaint);
  42. }
  43. }

Layout使用

上面提及取出线条的位置,这里的定位就是通过XML的这个layout来定位的,而onLayout()方法中后面四个非常重要的int型方位参数就是父View建议并传下来的值

 
 
  1. <com.xxxx.android.view.VerticalDashView
  2. android:layout_width="4dp"
  3. android:layout_height="match_parent"
  4. android:layout_marginBottom="5dp"
  5. android:layout_marginTop="5dp" />

mRect成员变量保存上面Layout中定义的位置,然后再onDraw()方法中画出View即可。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值