開發(fā)中遇到需要畫虛線雕擂,我們首先就會想到ShapeDrawable,在布局中加一個View贱勃,并給它添加一個虛線背景捂刺,是挺簡單的谣拣。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="line">
<size android:height="1dp" />
<stroke
android:dashGap="4dp"
android:dashWidth="8dp"
android:width="1dp"
android:color="#ffeaebf0" />
</shape>
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_gravity="center_vertical"
android:layerType="software"
android:background="@drawable/shape_dash_line" />
添加虛線背景,好理解族展,可是android:layerType="software"是干什么的森缠?這是因為我們現(xiàn)在的手機默認都是開啟了硬件加速的,而dashGap不支持硬件加速仪缸,我們需要把硬件加速關了就好了贵涵。使用ShapeDrawable實現(xiàn)虛線的方式雖然簡單,但是簡單就意味著不靈活恰画。比如說要求虛線是根據(jù)用戶操作來判斷要不要添加的宾茂,要實現(xiàn)動態(tài)改變虛線的粗細和顏色等樣式呢,不可能一個顏色寫一個ShapeDrawable吧拴还,這種情況下就不如使用Canvas來實現(xiàn)方便了跨晴。
我們都知道Canvas只有drawLine方法,沒有畫虛線的方法片林,但是我們可以用畫筆Paint的setPathEffect(PathEffect effect)方法端盆,PathEffect一共有五個子類:ComposePathEffect, CornerPathEffect, DashPathEffect, DiscretePathEffect, PathDashPathEffect, SumPathEffect, 其中的DashPathEffect就是可以用來實現(xiàn)虛線效果的,但是通過查閱資料發(fā)現(xiàn)它有一個弊端:不支持硬件加速费封!好吧焕妙,那我們用drawPath來繪制路徑吧。
public class DashLineView extends View {
private Paint mPaint;
private Path mPath;
//虛線顏色
private int backgroundColor;
//虛線粗細
private int strokeWidth;
//虛線寬度
private int dashWidth;
//虛線隔斷寬度
private int dashSpaceWidth;
public DashLineView(Context context) {
super(context);
initView();
}
public DashLineView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
obtainAttributes(context, attrs);
initView();
}
public DashLineView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
obtainAttributes(context, attrs);
initView();
}
private void obtainAttributes(Context context, AttributeSet attrs) {
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.DashLineView);
backgroundColor = ta.getColor(R.styleable.DashLineView_pt_backgroundColor, getResources().getColor(R.color.line));
strokeWidth = ta.getInt(R.styleable.DashLineView_pt_strokeWidth, ScreenUtil.dip2px(context, 1));
dashWidth = ta.getInt(R.styleable.DashLineView_pt_dashWidth, ScreenUtil.dip2px(context, 4));
dashSpaceWidth = ta.getInt(R.styleable.DashLineView_pt_dashSpaceWidth, ScreenUtil.dip2px(context, 3));
ta.recycle();
}
private void initView(){
//使用isInEditMode解決可視化編輯器無法識別自定義控件的問題
if (isInEditMode()) {
return;
}
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
// 需要加上這句弓摘,否則畫不出東西
mPaint.setStyle(Paint.Style.STROKE);
mPath = new Path();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//自定義的View能夠使用wrap_content或者是match_parent的屬性
setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight());
}
@Override
protected void onDraw(Canvas canvas) {
mPaint.setColor(backgroundColor);
mPaint.setStrokeWidth(strokeWidth);
mPaint.setPathEffect(new DashPathEffect(new float[] { dashWidth, dashSpaceWidth }, 0));
int centerY = getHeight() / 2;
mPath.reset();
mPath.moveTo(0, centerY);
mPath.lineTo(getWidth(), centerY);
canvas.drawPath(mPath, mPaint);
}
public void setDashLineColor(int bgColor) {
this.backgroundColor = getResources().getColor(bgColor);
}
}
我這里只提供了setDashLineColor方法動態(tài)設置虛線的顏色焚鹊,大家可以根據(jù)需求自行添加方法。
/**
* 虛線顏色
* @param color
*/
public void setLineViewColor(int color){
mDashLineView.setDashLineColor(color);
}
attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="DashLineView">
<attr name="pt_backgroundColor" format="color"/>
<attr name="pt_strokeWidth" format="dimension"/>
<attr name="pt_dashWidth" format="dimension"/>
<attr name="pt_dashSpaceWidth" format="dimension"/>
</declare-styleable>
</resources>
ScreenUtil.java
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
原理上還真的是比較簡單的韧献,公司項目用到末患,以作記錄之用。以下是實現(xiàn)出的效果圖
1.png
2.png