赞
踩
最近在研究自定义的view,俗话说什么东西都得从简单到困难,而自定义view又是安卓进阶必备,所以今天开发一个很简单的自定义view的五角星,作为入门实战
首先新建一个Wujiaoxing的java文件继承view,实现俩个参数的构造方法就行了,因为我们只在布局中使用,如果要在java文件中使用,最好是把构造方法都实现一下,然后相互调用
首先实现onMeasure方法,
//定位屏幕的宽度
private int width;
//定义自定义view的中心点坐标
private int centerX, centerY;
public Wujiaoxing(Context context, AttributeSet attrs) {
super(context, attrs);
//加个背景颜色,用来区分我们自定义的大小
setBackgroundColor(0x44ff0000);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
//设置view的宽度是屏幕宽度和高度中的最小值
width = Math.min(widthSize, heightSize);
//当出现这个特殊情况的时候,把屏幕的宽度作为view的宽度
if (heightMode == MeasureSpec.UNSPECIFIED) {
width = widthSize;
} else if (widthMode == MeasureSpec.UNSPECIFIED) {
width = heightSize;
}
centerX = width / 2;
centerY = width / 2;
//因为是正方形,所以宽度和高度一样
setMeasuredDimension(width, width);
}
onMeasure是测量出我们需要的view的高度,比如我们需要一个正方形
简单的解释一下,MeasureSpec.getSize(widthMeasureSpec);拿到屏幕的宽度,
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
拿到宽度的mode,mode分为3个模式,分别对应view的高度,宽度的大小
3个模式分别为EXACTLY和AT_MOST,UNSPECIFIED
1、MeasureSpec.UNSPECIFIED,父视图不对子视图施加任何限制,子视图可以得到任意想要的大小;
2、MeasureSpec.EXACTLY,父视图希望子视图的大小是specSize中指定的大小;
3、MeasureSpec.AT_MOST,子视图的大小最多是specSize中的大小。
以上施加的限制只是父视图“希望”子视图的大小按MeasureSpec中描述的那样,但是子视图的具体大小取决于多方面的。
因为我们定义的view是正方形,所以宽度和高度是相等的
然后在layout中看下效果
可以看到,我们自定义view的大小已经出来了,而且是正方形的
,然后我们开始绘制五角星,首先需要确定的是五个点的坐标
首先中心点的坐标很明显就是width/2,width/2
我们把左上角看成0,0
那么第一个点的坐标是centerX,0
第二个点的坐标是0,centerX/2
这样分别得到5个点的坐标
public List<Point> getFivePoint() {
mPointList.clear();
for (int i = 0; i < 6; i++) {
mPointList.add(getPoint(i));
}
return mPointList;
}
//采取4-1-5-2-3-4这样的顺序定义点的坐标
private Point getPoint(int position) {
int x = 0;
int y = 0;
if (position == 0) {
x = (centerX / 2);
y = width;
} else if (position == 1) {
x = centerX;
y = 0;
} else if (position == 2) {
x = centerX * 3 / 2;
y = width;
} else if (position == 3) {
x = 0;
y = centerY / 2;
} else if (position == 4) {
x = width;
y = centerY / 2;
} else if (position == 5) {
x = (centerX / 2);
y = width;
}
return new Point(x, y);
}
使用系统graphics包中的point用来存储x,y值
并创建一个list用来放置这5个点
现在我们有了存放这5个点坐标的集合mlistPoint
接下来就可以绘制了
采取4-1-5-2-3-4这样的顺序进行绘线
接下来实现onDraw方法
首先初始化我们的画笔
private void init() {
mPaint.setColor(0x88000000);
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.STROKE);
}
在view的构造函数中调用初始化操作
然后实现ondraw方法
@Override
protected void onDraw(Canvas canvas) {
getFivePoint();
Path path = new Path();
//首先将path移动到第一个点,然后往下一个点画,绘制的基础代码,一看就能明白的
for (int i = 0; i < mPointList.size() - 1; i++) {
path.moveTo(mPointList.get(i).x, mPointList.get(i).y);
path.lineTo(mPointList.get(i + 1).x, mPointList.get(i + 1).y);
}
canvas.drawPath(path, mPaint);
//用下面这种方法也可以
// canvas.drawLine(centerX, centerY, mPointList.get(i).x, mPointList.get(i).y, mPaint);
}
接下来在我们的layout中build一下文件,五角星就出来了
下面贴出全部的代码
package com.demo.swt.mystudyappshop.Wight;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
/**
* 介绍:这里写介绍
* 作者:sweet
* 邮箱:sunwentao@imcoming.cn
* 时间: 2017/2/17
*/
public class CstWuJiaoXingView extends View {
private int width;
private Paint mPaint = new Paint();
private List<Point> mPointList = new ArrayList<>();
private int centerX, centerY;
public CstWuJiaoXingView(Context context, AttributeSet attrs) {
super(context, attrs);
setBackgroundColor(0x44ff0000);
init();
}
private void init() {
mPaint.setColor(0x88000000);
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.STROKE);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
width = Math.min(widthSize, heightSize);
if (heightMode == MeasureSpec.UNSPECIFIED) {
width = widthSize;
} else if (widthMode == MeasureSpec.UNSPECIFIED) {
width = heightSize;
}
centerX = width / 2;
centerY = width / 2;
setMeasuredDimension(width, width);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
centerX = w / 2;
centerY = w / 2;
}
@Override
protected void onDraw(Canvas canvas) {
getFivePoint();
Path path = new Path();
for (int i = 0; i < mPointList.size() - 1; i++) {
path.moveTo(mPointList.get(i).x, mPointList.get(i).y);
path.lineTo(mPointList.get(i + 1).x, mPointList.get(i + 1).y);
}
canvas.drawPath(path, mPaint);
// canvas.drawLine(centerX, centerY, mPointList.get(i).x, mPointList.get(i).y, mPaint);
}
public List<Point> getFivePoint() {
mPointList.clear();
for (int i = 0; i < 6; i++) {
mPointList.add(getPoint(i));
}
return mPointList;
}
private Point getPoint(int position) {
int x = 0;
int y = 0;
if (position == 0) {
x = (centerX / 2);
y = width;
} else if (position == 1) {
x = centerX;
y = 0;
} else if (position == 2) {
x = centerX * 3 / 2;
y = width;
} else if (position == 3) {
x = 0;
y = centerY / 2;
} else if (position == 4) {
x = width;
y = centerY / 2;
} else if (position == 5) {
x = (centerX / 2);
y = width;
}
return new Point(x, y);
}
}
然后是layout文件的
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.demo.swt.mystudyappshop.Wight.CstWuJiaoXingView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
代码虽然很简单,但是什么事情都是从基础开始的,
下一期会带来一个五子棋游戏的简单制作,根据hyman大神的课程,编写的。用来作为我的记录
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。