之前项目中需要虚线,直接在drawable里写了xml形式的效果,后来发现在5.0以后的手机上显示有问题,不知道是偶然还是什么,就决定自己画个。。。效果实在简单,因为我从来没有自己画过自定义view!!!
好了,决定下来就开始画,买的书上大概看了下有流程,其实还是要熟悉view的绘制过程。
1,在values文件夹下新建attrs,为了存放我们虚线的一些属性,以及可以在布局中调用设置。简单分析下,虚线有间隔,虚线格宽度和高度,还有虚线的颜色。
<declare-styleable name="dashLineView">
<attr name="dash_gap" format="dimension"/>
<attr name="dash_width" format="dimension"/>
<attr name="dash_height" format="dimension"/>
<attr name="dash_color" format="color"/>
</declare-styleable>
后面的format是你属性的属性值类型。
我们可以在代码中获取到这些设置。
package com.example.zouwansheng.mydiyview.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import com.example.zws.mydiyview.R;
import com.example.zws.mydiyview.utils.DimenUtil;
/**
* Created by zws on 2016/4/28.
*/
public class DashLineView extends View{
private Context mContext;
private float mDashgap;//虚线格之间间距
private float mDashwidth;//虚线格的宽度
private float mDashheight;//虚线格的高度
private int mDashColor;//虚线格的颜色
private Paint mPaint;//画笔
public DashLineView(Context context) {
this(context, null);
}
public DashLineView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DashLineView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.mContext = context;
TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.dashLineView);
mDashgap = typedArray.getDimension(R.styleable.dashLineView_dash_gap, DimenUtil.dip2px(mContext,5));
mDashwidth = typedArray.getDimension(R.styleable.dashLineView_dash_width,DimenUtil.dip2px(mContext,5));
mDashheight = typedArray.getDimension(R.styleable.dashLineView_dash_height,DimenUtil.dip2px(mContext,1));
mDashColor = typedArray.getColor(R.styleable.dashLineView_dash_color, Color.parseColor("#d1d1d1"));
typedArray.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(mDashheight);//画笔的宽度,其实就是虚线的高度
mPaint.setColor(mDashColor);
int width = getMeasuredWidth();
int height = getMeasuredHeight();
float length = mDashgap + mDashwidth;
int num = (int) Math.floor(width/length);
for (int i=0;i<num;i++){
canvas.drawLine(i*length,0,i*length+mDashwidth,height,mPaint);
}
}
}
代码放上了,我就说下步骤。
第一步,继承view,实现几个构造方法。本来是四个,最后一个没有用就去掉了。为什么要写这三个,因为手机类型不同,有时候咱也不知道会走哪一个,普遍说的是第二个,
所以咱就把第一个指向第二个,第二个指向第三个,这样就确保不会出错。
在第三个构造方法里面,我们要获得我们四个属性。
通过typedarray实例获取我们之前在attrs里面四个属性,与代码里对应上,获取我们之后如果在布局中给这些属性赋值了的值。
第二步,重写onMeasure方法,可写可不写,测量的一个方法,我们不需要。有时候要重写,下次我会练下复杂的!
第三步,重写onDraw方法,这里就需要绘制虚线了,获取画笔paint,设置画笔的类型STROKE,画笔的宽度和高度。然后,我们要获取虚线的宽度和高度,这里的宽度和高度,就是我们要最终画成的效果虚线的宽度和高度。有时候虚线两边还会有margin,也需要注意虚线的实际长度要减去这两边的margin距离。
画笔开始画!我们用一个循环,但是画笔一次要画多长?画多少次?起始x,y坐标?画一次的最终x,y坐标?
所以我们定义了个length,就是一次画多长,根据最终虚线的长度算出来需要画多少次num。
其实我这里做复杂了,一次的length就可以是一个虚线格的宽度,终点x坐标就可以是i*length+mDashgap。num算法应该不变。
好了。这里我们就画好了。
第四步,去布局文件里,
<com.example.zouwansheng.mydiyview.view.DashLineView
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:layout_marginTop="30dp"
app:dash_width="10dp"
/>
这里,如果要给dash_width赋值,需要在头部添加xmln:app=“”。。。
不然会报错。
好了,效果就那样子,可以自己调。
自己一步步敲过来,写的有点详细,可能有些理解是错的,肯定有错的!望懂的人看到了指导一下。