Android自定義View之繪制虛線

開發(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
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末锤窑,一起剝皮案震驚了整個濱河市阻塑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌果复,老刑警劉巖陈莽,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異虽抄,居然都是意外死亡走搁,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門迈窟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來私植,“玉大人,你說我怎么就攤上這事车酣∏冢” “怎么了索绪?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長贫悄。 經(jīng)常有香客問我瑞驱,道長,這世上最難降的妖魔是什么窄坦? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任唤反,我火速辦了婚禮,結(jié)果婚禮上鸭津,老公的妹妹穿的比我還像新娘彤侍。我一直安慰自己,他們只是感情好逆趋,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布盏阶。 她就那樣靜靜地躺著,像睡著了一般闻书。 火紅的嫁衣襯著肌膚如雪名斟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天惠窄,我揣著相機與錄音蒸眠,去河邊找鬼漾橙。 笑死杆融,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的霜运。 我是一名探鬼主播脾歇,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼淘捡!你這毒婦竟也來了藕各?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤焦除,失蹤者是張志新(化名)和其女友劉穎激况,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體膘魄,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡乌逐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了创葡。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浙踢。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖灿渴,靈堂內(nèi)的尸體忽然破棺而出洛波,到底是詐尸還是另有隱情胰舆,我是刑警寧澤,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布蹬挤,位于F島的核電站缚窿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏闻伶。R本人自食惡果不足惜滨攻,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蓝翰。 院中可真熱鬧光绕,春花似錦、人聲如沸畜份。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽爆雹。三九已至停蕉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間钙态,已是汗流浹背慧起。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留册倒,地道東北人蚓挤。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像驻子,于是被迫代替她去往敵國和親灿意。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355