Android 繪制虛線
AndroidView
簡單需求
先來看看這麼一個需求
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SNyAzMwEjNyATM1EDMyMXMzFDe15Was9CXt92Yu4GZkV3bsNmLix2ZuAjeuETbvNmL5wmbph3Nvw1LcpDc0RHaiojIsJye.png)
水準虛線
如果需要完成上面的水準虛線,可以這樣處理。聲明shape,其中dashGap是虛線的間隔寬度,dashWidth是實線的間隔寬度,stroke翻譯過來是名詞,畫
android:shape="line">
android:width="1dp"
android:dashGap="3dp"
android:dashWidth="3dp"
android:color="#ffececec"/>
然後可以在layout檔案中直接使用
android:layout_width="match_parent"
android:layout_height="2dp"
android:contentDescription="@string/contentDescription"
android:layerType="software"
android:background="@drawable/dash_line"/>
豎直虛線
按照上面的實作思路,把水準線直接轉換為豎直線就可以,實作上并沒有什麼難點
android:layout_width="2dp"
android:layout_height="match_parent"
android:contentDescription="@string/contentDescription"
android:layerType="software"
android:background="@drawable/dash_line"/>
然後運作,你會很驚訝的發現,居然啥也顯示不出來,這是弄啥咧?然後慌張的打開Stack Overflow,然後驚奇的發現,豎直虛線需要在水準虛線基礎上旋轉90
android:left="-300dp"
android:right="-300dp">
android:drawable="@drawable/dash_line"
android:fromDegrees="90"
android:toDegrees="90"
android:visible="true"/>
shape準備好以後,直接拿過來使用即可
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即可。
自定義DashView實作
publicclassVerticalDashViewextendsView{
privatePaintmDashPaint;
privateRectmRect;
publicVerticalDashView(Contextcontext,AttributeSetattrs){
super(context,attrs);
init();
}
@SuppressLint({"InlinedApi","NewApi"})
privatevoidinit(){
if(Build.VERSION.SDK_INT>=11){
setLayerType(View.LAYER_TYPE_SOFTWARE,null);
}
finalDisplayMetricsmetrics=getResources().getDisplayMetrics();
floatwidth=TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,metrics);
floatdashGap=TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,3,metrics);
floatdashWidth=TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,3,metrics);
mDashPaint=newPaint();
mDashPaint.setColor(0xffececec);
mDashPaint.setStyle(Style.STROKE);
mDashPaint.setStrokeWidth(width);
mDashPaint.setAntiAlias(true);
//DashPathEffect是Android提供的虛線樣式API,具體的使用可以參考下面的介紹
mDashPaint.setPathEffect(newDashPathEffect(newfloat[]{dashWidth,dashGap},0));
mRect=newRect();
}
@Override
protectedvoidonLayout(booleanchanged,intleft,inttop,intright,intbottom){
super.onLayout(changed,left,top,right,bottom);
//取出線條的位置(位置的定義放在XML的layout中,具體如下xml檔案所示)
mRect.left=left;
mRect.top=top;
mRect.right=right;
mRect.bottom=bottom;
}
@Override
protectedvoidonDraw(Canvascanvas){
floatx0=(mRect.right-mRect.left)/2f;
floaty0=0;
floatx1=x0;
floaty1=y0+mRect.bottom-mRect.top;
canvas.drawLine(x0,y0,x1,y1,mDashPaint);
}
}
Layout使用
上面提及取出線條的位置,這裡的定位就是通過XML的這個layout來定位的,而onLayout()方法中後面四個非常重要的int型方位參數就是父View建議并傳下來的值
android:layout_width="4dp"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"/>
mRect成員變量儲存上面Layout中定義的位置,然後再onDraw()方法中畫出View即可。
補充說明(DashPathEffect)
DashPathEffect是PathEffect類的一個子類,可以使paint畫出類似虛線的樣子,并且可以任意指定虛實的排列方式.
代碼中的float數組,必須是偶數長度,且>=2,指定了多少長度的實線之後再畫多少長度的空白.
如本代碼中,繪制長度5的實線,再繪制長度10的空白,再繪制長度15的實線,再繪制長度20的空白,依次重複。