自定义view的简单实现(一)

来源:互联网 发布:万网域名申请流程 编辑:程序博客网 时间:2024/06/11 13:41

自定义view(一)

简单的五角星绘制

最近在研究自定义的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大神的课程,编写的。用来作为我的记录

0 0
原创粉丝点击