亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android自定義View實現繪制虛線的方法詳解

發布時間:2020-10-05 03:10:44 來源:腳本之家 閱讀:338 作者:Android雜貨鋪 欄目:移動開發

前言

說實話當第一次看到這個需求的時候,第一反應就是Canvas只有drawLine方法,并沒有drawDashLine方法啊!這咋整啊,難道要我自己做個遍歷不斷的drawLine?不到1秒,我就放棄這個想法了,因為太惡心了。方法肯定是有的,只不過我不知道而已。

繪制方法

最簡單的方法是利用ShapeDrawable,比如說你想用虛線要隔開兩個控件,就可以在這兩個控件中加個View,然后給它個虛線背景。

嗯,理論上就是這樣子的,實現上也很簡單。

<!-- drawable 文件 -->
<?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:color="@color/dash_line"
 android:dashGap="2dp"
 android:dashWidth="3dp"/>
</shape>
<!-- 布局文件 -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:id="@+id/activity_main"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:orientation="vertical"
 android:gravity="center"
 tools:context="hope.example.dashlinedemo.MainActivity">

 <TextView
 android:layout_width="match_parent"
 android:layout_height="40dp"
 android:gravity="center"
 android:text="分享給微信好友"/>

 <View
 android:layout_width="match_parent"
 android:layout_height="2dp"
 android:background="@drawable/dash_line" />

 <TextView
 android:layout_width="match_parent"
 android:layout_height="40dp"
 android:gravity="center"
 android:text="分享至朋友圈" />
</LinearLayout>

寫完之后,從Android Studio的預覽功能上就可以看到效果了。

Android自定義View實現繪制虛線的方法詳解

是不是很簡單呢?慢著,先別高興得太早了,真機上跑一下看看效果先。

Android自定義View實現繪制虛線的方法詳解

這什么鬼,明明是虛線才對的啊,Studio上的預覽也可以看出代碼沒問題的。其實,這是因為我們現在的手機默認都是開啟了硬件加速的,而dashGap不支持硬件加速,我們只需要修改下View的參數,把硬件加速關了就好了。

<View
 android:layout_width="match_parent"
 android:layout_height="2dp"
 android:background="@drawable/dash_line"
 android:layerType="software"/>

使用ShapeDrawable實現虛線的方式雖然簡單,但是簡單就意味著不靈活。比如說要求虛線是根據用戶操作來判斷要不要添加的,這種情況下就不如使用Canvas來實現方便了。

前面說了,Canvas只有drawLine方法,沒有drawDashLine方法。但是你要知道,畫什么雖然是Canvas決定的,但是怎么畫卻是由畫筆Paint決定的。接下來看看這神奇的畫筆怎么幫我們把直線畫成虛的吧。

Paint有setPathEffect(PathEffect effect)這么一個方法,PathEffect一共有五個子類:ComposePathEffect, CornerPathEffect, DashPathEffect, DiscretePathEffect, PathDashPathEffect, SumPathEffect, 其中的DashPathEffect就是我們需要的虛線效果,其它的幾種效果大家可以自己試一試。

DashPathEffect的創建需要兩個參數,一個float數組,代表實線與空白處的長度。比如說我給的參數是new float[] {10, 5} ,那么虛線的一個單位就是10像素的實線加上5像素的空白,然后以它為單位去不斷重復畫,從而形成一條虛線。而如果設定的參數是new float[] {10, 5,20, 10},那么虛線的一個單位就是由10像素實線,5像素空白,20像素實線,10像素空白組成的虛線段。

另一個參數代表偏移,一般我們設置為0即可,如果要實現虛線的動畫效果的話,可以不斷改變這個值,從而讓虛線動起來。

接著實現這個自定義View,并將它代替上面xml文件中的虛線(View)即可。

public class DashLineView extends View {

 private Paint mPaint;

 public DashLineView(Context context, AttributeSet attrs) {
 super(context, attrs);

 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
 mPaint.setColor(getResources().getColor(R.color.dash_line));
 mPaint.setStrokeWidth(3);
 mPaint.setPathEffect(new DashPathEffect(new float[] {5, 5}, 0));

 }

 @Override
 protected void onDraw(Canvas canvas) {
 int centerY = getHeight() / 2;
 canvas.drawLine(0, centerY, getWidth(), centerY, mPaint);
 }
}

代碼跑起來之后又發現虛線變成了直線,根本就沒有效果。有了上面使用ShapeDrawable的經驗之后,我們完全有理由猜測這是由于硬件加速引起的,到官方文檔硬件加速上可以看到確實是因為硬件加速導致的。

(PS:其實真實情況是我先自定義View后才知道ShapeDrawable沒有虛線效果可能也是因為硬件加速引起的。)

Android自定義View實現繪制虛線的方法詳解

重新修改onDraw方法。重新運行之后,虛線就正常出現了。

@Override
protected void onDraw(Canvas canvas) {
 int centerY = getHeight() / 2;
 setLayerType(LAYER_TYPE_SOFTWARE, null);
 canvas.drawLine(0, centerY, getWidth(), centerY, mPaint);
}

使用shapeDrawable和drawLine方法都能實現虛線的效果,但它們的缺點也很明顯,就是不支持硬件加速。上面的代碼因為簡單,所以不會引起卡頓的問題,但是如果你的自定義View很復雜,比如說用戶在畫矩形框的時候,如果用戶拉出來的圖形是一個正方形,那我們就畫一條對角虛線來提醒用戶。這種情況下不支持硬件加速的弊端可能就會顯現出來了。好在我們還有其它方法來實現虛線的繪制。setPathEffect方法只是不支持直線而已,那我們就找找有沒有另外的方式來畫直線,drawPath就可以繪制各種路徑,當然也可以幫我們繪制直線,雖然說有點大材小用了。

重新來看看代碼怎么寫。

public class DashLineView extends View {

 private Paint mPaint;
 private Path mPath;

 public DashLineView(Context context, AttributeSet attrs) {
 super(context, attrs);

 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
 mPaint.setColor(getResources().getColor(R.color.dash_line));
 // 需要加上這句,否則畫不出東西
 mPaint.setStyle(Paint.Style.STROKE);
 mPaint.setStrokeWidth(3);
 mPaint.setPathEffect(new DashPathEffect(new float[] {15, 5}, 0));

 mPath = new Path();
 }

 @Override
 protected void onDraw(Canvas canvas) {
 int centerY = getHeight() / 2;
 mPath.reset();
 mPath.moveTo(0, centerY);
 mPath.lineTo(getWidth(), centerY);
 canvas.drawPath(mPath, mPaint);
 }
}

setLayerType(LAYER_TYPE_SOFTWARE, null);這一句代碼去掉之后也還能畫出虛線,證明是支持硬件加速的。

至此,我們已經完美的實現了虛線的繪制,但本篇文章還沒完呢!我們繪制出來的虛線是一個實心矩形,那如果我們要求這條是由實心圓形組成的呢?又或者是其它圖形組成的呢?這時候我們就可以用PathDashPathEffect來實現了,看清楚點,是PathDashPathEffect而不是DashPathEffect!PathDashPathEffect允許我們添加一個路徑來定義虛線的樣式。我們把setPathEffect()改一下,看看效果。

Path path = new Path();
path.addCircle(0, 0, 3, Path.Direction.CW);
mPaint.setPathEffect(new PathDashPathEffect(path, 15, 0, PathDashPathEffect.Style.ROTATE));

其實圓形組成的虛線也挺好看的嘛。繪制虛線至此就講完了,但如果要我們給這條虛線加一些效果呢?比如說虛線由中間是完全不透明的,而兩邊則會慢慢變透明。是不是想打人了,又不是不能用,那么多要求干嘛!沒辦法,硬著頭皮來吧。Paint還有另外一個方法,setShader(Shader shader) ,Shader我們可以理解為著色器,它有一個子類是LinearGradient,利用它可以幫助我們實現線性變色。看看代碼先。

為了讓效果突出一點,把虛線的顏色調為黑色。

// 其它方法還是不變
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
 super.onSizeChanged(w, h, oldw, oldh);

 // 前四個參數沒啥好講的,就是起點和終點而已。
 // color數組的意思是從透明 -> 黑 -> 黑 -> 透明。
 // float數組與color數組對應:
 // 0 -> 0.3 (透明 -> 黑)
 // 0.3 - 0.7 (黑 -> 黑,即不變色)
 // 0.7 -> 1 (黑 -> 透明)
 mPaint.setShader(new LinearGradient(0, 0, getWidth(), 0,
  new int[] {Color.TRANSPARENT, Color.BLACK, Color.BLACK, Color.TRANSPARENT},
  new float[] {0, 0.3f, 0.7f, 1f}, Shader.TileMode.CLAMP));
}

Android自定義View實現繪制虛線的方法詳解

效果還是可以的嘛,當然不是應用在圖片上的這種場景。好了,這次是真的講完了。雖然畫虛線不難,但還是有一些值得注意的地方的(硬件加速),然后再細細玩一玩,雖然簡單,還是可以玩出一些花樣來的。

總結

以上就是這篇文章的全部內容了,希望本文的內容對各位Android開發者們能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

伊宁县| 郓城县| 离岛区| 岱山县| 兰西县| 新巴尔虎左旗| 翁源县| 哈尔滨市| 台北县| 佛冈县| 本溪市| 炉霍县| 景宁| 古丈县| 恭城| 樟树市| 沅陵县| 高雄市| 玉龙| 亚东县| 阳泉市| 上虞市| 侯马市| 涞源县| 闸北区| 昔阳县| 孙吴县| 波密县| 台北县| 社旗县| 河曲县| 白朗县| 海伦市| 黔东| 天长市| 玛多县| 黄石市| 静乐县| 鲁山县| 东乡| 利辛县|