@linux1s1s
2015-10-26T15:15:23.000000Z
字数 3391
阅读 10946
AndroidView
先来看看这么一个需求
如果需要完成上面的水平虚线,可以这样处理。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="line" >
<stroke
android:width="1dp"
android:dashGap="3dp"
android:dashWidth="3dp"
android:color="#ffececec" />
<size android:height="1dp"/>
</shape>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:contentDescription="@string/contentDescription"
android:layerType="software"
android:background="@drawable/dash_line" />
按照上面的实现思路,把水平线直接转换为竖直线就可以,实现上并没有什么难点
<View
android:layout_width="2dp"
android:layout_height="match_parent"
android:contentDescription="@string/contentDescription"
android:layerType="software"
android:background="@drawable/dash_line" />
然后运行,你会很惊讶的发现,居然啥也显示不出来,这是弄啥咧?然后慌张的打开Stack Overflow,然后惊奇的发现,竖直虚线需要在水平虚线基础上旋转90
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:left="-300dp"
android:right="-300dp">
<rotate
android:drawable="@drawable/dash_line"
android:fromDegrees="90"
android:toDegrees="90"
android:visible="true" />
</item>
</layer-list>
shape准备好以后,直接拿过来使用即可
<View
android:layout_width="4dp"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:background="@drawable/dash_vertical_line"
android:contentDescription="@string/app_name"
android:layerType="software" />
这样很轻松就把水平虚线转换成了竖直虚线,但是上面的实现方式会遇到如下问题:
在小米1S真机上显示不出来,原因是不支持LAYER_TYPE_SOFTWARE
针对上面的问题,可以通过最原始的canvas画线来解决,因为代码比较简单,这里直接给出code即可。
public class VerticalDashView extends View {
private Paint mDashPaint;
private Rect mRect;
public VerticalDashView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
@SuppressLint({ "InlinedApi", "NewApi" })
private void init() {
if (Build.VERSION.SDK_INT >= 11) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
final DisplayMetrics metrics = getResources().getDisplayMetrics();
float width = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, metrics);
float dashGap = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, metrics);
float dashWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, metrics);
mDashPaint = new Paint();
mDashPaint.setColor(0xffececec);
mDashPaint.setStyle(Style.STROKE);
mDashPaint.setStrokeWidth(width);
mDashPaint.setAntiAlias(true);
//DashPathEffect是Android提供的虚线样式API,具体的使用可以参考下面的介绍
mDashPaint.setPathEffect(new DashPathEffect(new float[] { dashWidth, dashGap }, 0));
mRect = new Rect();
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
//取出线条的位置(位置的定义放在XML的layout中,具体如下xml文件所示)
mRect.left = left;
mRect.top = top;
mRect.right = right;
mRect.bottom = bottom;
}
@Override
protected void onDraw(Canvas canvas) {
float x0 = (mRect.right - mRect.left) / 2f;
float y0 = 0;
float x1 = x0;
float y1 = y0 + mRect.bottom - mRect.top;
canvas.drawLine(x0, y0, x1, y1, mDashPaint);
}
}
上面提及取出线条的位置,这里的定位就是通过XML的这个layout来定位的,而onLayout()方法中后面四个非常重要的int型方位参数就是父View建议并传下来的值
<com.xxxx.android.view.VerticalDashView
android:layout_width="4dp"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp" />
mRect成员变量保存上面Layout中定义的位置,然后再onDraw()方法中画出View即可。
DashPathEffect是PathEffect类的一个子类,可以使paint画出类似虚线的样子,并且可以任意指定虚实的排列方式.
代码中的float数组,必须是偶数长度,且>=2,指定了多少长度的实线之后再画多少长度的空白.
如本代码中,绘制长度5的实线,再绘制长度10的空白,再绘制长度15的实线,再绘制长度20的空白,依次重复。