做了一个自定义View波浪线,记录下
一,自定义控件介绍
一般android中开发自定义控件包含组合控件,把现有的控件组合起来,加上动画,继承现有控件,做增强功能,继承View,完全自定义控件,继承ViewGroup,完全自定义控件。一般自定义控件有三个重新方法分别是onMeasure()测量控件,onLayout()摆放控件,onDraw()绘制控件.关于画笔和路径有一个地址详细介绍http://www.open-open.com/lib/view/open1477882828066.html
二,自定义View波浪线就是通过继承View,然后利用paint和path绘制出来,有些问题在代码中有注释方便查看
public class WaveLineView extends View {
public static final int DEF_SIZE = 50;
public static final int DEF_COLOR = Color.BLACK;
public static final int DEF_LITUDE = 10;
public static final float DEF_WIDTH = 2.0f;
public static final float DEF_PERIOD = (float) (2 * Math.PI / 180);//Mathi.pi圆周率
private Path mPath;
private Paint mPaint;
private int mLitude;
private int mColor = DEF_COLOR;
private float mPeriod;
private float mWidth = DEF_WIDTH;
public WavyLineView(Context context) {
this(context, null);
}
public WavyLineView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public WavyLineView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public WavyLineView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(attrs);
}
/**
*初始化view控件
*/
private void init(AttributeSet attrs) {
TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.WavyLineView);
mColor = ta.getColor(R.styleable.WavyLineView_strokeColor, DEF_COLOR);
mPeriod = ta.getFloat(R.styleable.WavyLineView_period, DEF_PERIOD);
mLitude = ta.getDimensionPixelOffset(R.styleable.WavyLineView_amplitude, DEF_LITUDE);
mWidth = ta.getDimensionPixelOffset(R.styleable.WavyLineView_strokeWidth, dp2px(getContext(), DEF_WIDTH));
ta.recycle();
mPath = new Path(); //创建路径
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); //创建画笔
mPaint.setStyle(Paint.Style.STROKE);//设置画笔风格,空心或者实心
mPaint.setAntiAlias(true);//设置是否抗锯齿
mPaint.setStrokeCap(Paint.Cap.ROUND); //设置画笔的类型
mPaint.setColor(mColor);
mPaint.setStrokeWidth(dp2px(getContext(), mWidth));//设置画笔宽度
/** setAntiAlias: 设置画笔的锯齿效果。
setColor: 设置画笔颜色
setARGB: 设置画笔的a,r,p,g值。
setAlpha: 设置Alpha值
setTextSize: 设置字体尺寸。
setStyle: 设置画笔风格,空心或者实心。
setStrokeWidth: 设置空心的边框宽度。
getColor: 得到画笔的颜色
getAlpha: 得到画笔的Alpha值
*/
}
/**
*测量控件
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(measureSize(widthMeasureSpec), measureSize(heightMeasureSpec));
}
/**
*绘制控件
*/
@Override
protected void onDraw(Canvas canvas) {
calculatePath();
canvas.drawPath(mPath, mPaint);
}
//MeasureSpec包含Mode和Size,其中AT_Most为wrap,Exactly设置确切参数,Unspecified设置为match
private int measureSize(int measureSpec) {
int defSize = dp2px(getContext(), DEF_SIZE);
int specSize = MeasureSpec.getSize(measureSpec);
int specMode = MeasureSpec.getMode(measureSpec);
int result = 0;
switch (specMode) {
case MeasureSpec.UNSPECIFIED:
case MeasureSpec.AT_MOST:
result = Math.min(defSize, specSize);
break;
case MeasureSpec.EXACTLY:
result = specSize;
break;
}
return result;
}
//绘制从左上角开始根据上下左右绘制
private void calculatePath() {
mPath.reset();
float y;
float left = getPaddingLeft();
float right = getMeasuredWidth() - getPaddingRight();
float top = getPaddingTop();
float bottom = getMeasuredHeight() - getPaddingBottom();
mPath.moveTo(left, (top + bottom) / 2);
//通过正弦函数绘制x,y路径
for (float x = 0; x <= right; x = x+1) {
y = (float) (mLitude * Math.sin(mPeriod * x) + (top + bottom) / 2); //Math.sin正
mPath.lineTo(x + left, y);
}
}
/**
*设置波浪上下波动
*/
public void setLitude(int amplitude) {
this.mLitude = amplitude;
invalidate();
}
/**
*设置波浪频率
*/
public void setPeriod(float T) {
this.mPeriod = T;
invalidate();//调用此方法重新绘制view
}
/**
*设置波浪颜色
*/
public void setColor(int color) {
this.mColor = color;
mPaint.setColor(mColor);
invalidate();
}
/**
*设置波浪宽度
*/
public void setWidth(float strokeWidth) {
this.mWidth = strokeWidth;
mPaint.setStrokeWidth(mWidth);
invalidate();
}
/**
*dp->px工具方法
*/
public static int dp2px(Context context, float dipValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dipValue * scale + 0.5f);
}
}
三,在Activity中的使用,直接全类名在布局文件中使用
1,布局文件
<com.tstest.www.waveline.WaveLineView
android:id="@+id/wavyLineView"
android:layout_width="match_parent"
android:layout_height="200dp"/>
2,activity中代码直接调用相应方法
final WavyLineView mWavyLineView = (WavyLineView) findViewById(R.id.wavyLineView);
float initPeriod = (float) (2 * Math.PI / 180);
int initLitude = 30;
int initWidth = 3;
mWavyLineView .setPeriod(initPeriod);//设置左右频率
mWavyLineView .setLitude(initLitude);//设置上下波动
mWavyLineView .setColor(Color.BLACK);//设置颜色
mWavyLineView .setWidth(dp2px(this, initWidth));