Android 画一个太极图实例代码

今天练手一下,一起来画个太极图吧~

最终效果如下:

最终效果

一般都是先讲原理,我就反其道而行,先讲实现吧。

1.继承实现初始化方法

继承View,实现基本的构造函数:

public TestView(Context context) {
  this(context, null);
}

public TestView(Context context, AttributeSet attrs) {
  this(context, attrs, 0);
}

public TestView(Context context, AttributeSet attrs, int defStyleAttr) {
  this(context, attrs, defStyleAttr, 0);
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public TestView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
  super(context, attrs, defStyleAttr, defStyleRes);
  init();
}

在init()方法中,进行初始化操作,这里初始化一下画笔就好。

private Paint mPaint;

private void init() {
  initPaint();
}

/**
 * 初始化画笔
 */
private void initPaint() {
  mPaint = new Paint();        //创建画笔对象
  mPaint.setColor(Color.BLACK);    //设置画笔颜色
  mPaint.setStyle(Paint.Style.FILL); //设置画笔模式为填充
  mPaint.setStrokeWidth(10f);     //设置画笔宽度为10px
  mPaint.setAntiAlias(true);     //设置抗锯齿
  mPaint.setAlpha(255);        //设置画笔透明度
}

在onSizeChanged()方法中获取高宽,便于之后绘制计算。

private int mWidth;
private int mHeight;  

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  super.onSizeChanged(w, h, oldw, oldh);
  mWidth = w;
  mHeight = h;
}

创建两个路径,一下计算就在这两个路径中进行。

private Path path0 = new Path();
private Path path1 = new Path();

然后到最关键的onDraw()方法了,这里会分几步来演示。

1.移动布局到中间

@Override
protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  //移动布局到中间
  canvas.translate(mWidth / 2, mHeight / 2);
}

ps:为了简洁,之后的代码都是在onDraw()中逐层增加的,之后就不写onDraw()的外出括号了。

2.画背景黄色

mPaint.setColor(0xffffff00);
  path0.addRect(-400, -400, 400, 400, Path.Direction.CW);
  canvas.drawPath(path0, mPaint);

第二步.png

3.画白色圆背景,即太极图的白鱼部分。

mPaint.setColor(0xffffffff);
path0.rewind();
path0.addCircle(0, 0, 200, Path.Direction.CW);
canvas.drawPath(path0, mPaint);

4.画黑色圆背景,即太极图的黑鱼部分,和白鱼一样大小位置,只是把白鱼盖住了,这里就需要用一些boolean运算进行绘制了。

//白鱼的背景
mPaint.setColor(0xffffffff);
path0.rewind();
path0.addCircle(0, 0, 200, Path.Direction.CW);
canvas.drawPath(path0, mPaint);

//黑鱼的背景
mPaint.setColor(0xff000000);
path1.addCircle(0, 0, 200, Path.Direction.CW);
canvas.drawPath(path0, mPaint);//这一段注意,之后要删除

第四步.png

5.对黑鱼(path1)进行boolean计算,把不需要的部分去掉。这里就是要把圆的右半边消除,这里就需要用到path.op()方法了。

mPaint.setColor(0xffffffff);
path0.rewind();
path0.addCircle(0, 0, 200, Path.Direction.CW);
canvas.drawPath(path0, mPaint);

mPaint.setColor(0xff000000);
path1.addCircle(0, 0, 200, Path.Direction.CW);

path0.rewind();
path0.addRect(0, -200, 200, 200, Path.Direction.CW);
path1.op(path0, Path.Op.DIFFERENCE);
canvas.drawPath(path0, mPaint);//这一段注意,之后要删除

第五步.png

6.这时候我们已经把不需要的另一半黑色去掉了,但是黑鱼应该有个圆的头,那么我们就拼接一个头给它。

mPaint.setColor(0xffffffff);
path0.rewind();
path0.addCircle(0, 0, 200, Path.Direction.CW);
canvas.drawPath(path0, mPaint);

mPaint.setColor(0xff000000);
path1.addCircle(0, 0, 200, Path.Direction.CW);

path0.rewind();
path0.addRect(0, -200, 200, 200, Path.Direction.CW);
path1.op(path0, Path.Op.DIFFERENCE);

path0.rewind();
path0.addCircle(0, -100, 100, Path.Direction.CW);
path1.op(path0, Path.Op.UNION);

canvas.drawPath(path1, mPaint);//这一段注意,之后要删除

第六步.png

7.到这里,我们看到,只需要在绘制一个白鱼的头就可以了,那么也和第五步一样,使用一个boolean运算把多余的黑色去掉即可。

mPaint.setColor(0xffffffff);
path0.rewind();
path0.addCircle(0, 0, 200, Path.Direction.CW);
canvas.drawPath(path0, mPaint);

mPaint.setColor(0xff000000);
path1.addCircle(0, 0, 200, Path.Direction.CW);

path0.rewind();
path0.addRect(0, -200, 200, 200, Path.Direction.CW);
path1.op(path0, Path.Op.DIFFERENCE);

path0.rewind();
path0.addCircle(0, -100, 100, Path.Direction.CW);
path1.op(path0, Path.Op.UNION);

path0.rewind();
path0.addCircle(0, 100, 100, Path.Direction.CW);
path1.op(path0, Path.Op.DIFFERENCE);
canvas.drawPath(path1, mPaint);

第七步.png

8.至此,已经绘制好了八卦图的背景了,只需要在绘制鱼的眼睛即可。

//画黑色小圆
path0.rewind();
path0.addCircle(0, 100, 50, Path.Direction.CW);
mPaint.setColor(0xff000000);
canvas.drawPath(path0, mPaint);

//画白色小圆
path0.rewind();
path0.addCircle(0, -100, 50, Path.Direction.CW);
mPaint.setColor(0xffffffff);
canvas.drawPath(path0, mPaint);

第八步.png

完成,最后上完整的代码。代码写得有点乱,不过也是练习而已,哈哈。至于其中的boolean运算什么的,之后在我的自定义View的笔记中在写吧。

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by Whitelaning on 2016/6/28.
 * Email: whitelaning@qq.com
 */
public class TestView extends View {

  private Paint mPaint;
  private int mWidth;
  private int mHeight;

  public TestView(Context context) {
    this(context, null);
  }

  public TestView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public TestView(Context context, AttributeSet attrs, int defStyleAttr) {
    this(context, attrs, defStyleAttr, 0);
  }

  @TargetApi(Build.VERSION_CODES.LOLLIPOP)
  public TestView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    init();
  }

  private void init() {
    initPaint();
  }

  /**
   * 初始化画笔
   */
  private void initPaint() {
    mPaint = new Paint();        //创建画笔对象
    mPaint.setColor(Color.BLACK);    //设置画笔颜色
    mPaint.setStyle(Paint.Style.FILL); //设置画笔模式为填充
    mPaint.setStrokeWidth(10f);     //设置画笔宽度为10px
    mPaint.setAntiAlias(true);     //设置抗锯齿
    mPaint.setAlpha(255);        //设置画笔透明度
  }

  @Override
  protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    mWidth = w;
    mHeight = h;
  }

  private Path path0 = new Path();
  private Path path1 = new Path();

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //移动布局到中间
    canvas.translate(mWidth / 2, mHeight / 2);

    //画大背景颜色
    mPaint.setColor(0xffffff00);
    path0.addRect(-400, -400, 400, 400, Path.Direction.CW);
    canvas.drawPath(path0, mPaint);

    mPaint.setColor(0xffffffff);
    path0.rewind();
    path0.addCircle(0, 0, 200, Path.Direction.CW);
    canvas.drawPath(path0, mPaint);

    mPaint.setColor(0xff000000);
    path1.addCircle(0, 0, 200, Path.Direction.CW);

    path0.rewind();
    path0.addRect(0, -200, 200, 200, Path.Direction.CW);
    path1.op(path0, Path.Op.DIFFERENCE);

    path0.rewind();
    path0.addCircle(0, -100, 100, Path.Direction.CW);
    path1.op(path0, Path.Op.UNION);

    path0.rewind();
    path0.addCircle(0, 100, 100, Path.Direction.CW);
    path1.op(path0, Path.Op.DIFFERENCE);
    canvas.drawPath(path1, mPaint);

    //画黑色小圆
    path0.rewind();
    path0.addCircle(0, 100, 50, Path.Direction.CW);
    mPaint.setColor(0xff000000);
    canvas.drawPath(path0, mPaint);

    //画白色小圆
    path0.rewind();
    path0.addCircle(0, -100, 50, Path.Direction.CW);
    mPaint.setColor(0xffffffff);
    canvas.drawPath(path0, mPaint);
  }
}

Whitelaning
It's very easy to be different but very difficult to be better

以上就是对Android 实现太极的实例代码,有兴趣朋友可以参考下,谢谢大家对本站的支持!

(0)

相关推荐

  • C语言/C++中如何产生随机数

    C语言/C++怎样产生随机数:这里要用到的是rand()函数, srand()函数,和time()函数. 需要说明的是,iostream头文件中就有srand函数的定义,不需要再额外引入stdlib.h;而使用time()函数需要引入ctime头文件. 使用rand()函数获取一个随机数如果你只要产生随机数而不需要设定范围的话,你只要用rand()就可以了:rand()会返回一随机数值, 范围在0至RAND_MAX 间.RAND_MAX定义在stdlib.h, 其值为2147483647. 例子

  • JS实现太极旋转思路分析

    刚学了js的一些函数,所以做了一个太极的旋转.做完之后是上面这个样子的,是可以旋转的. 思路: 1.先做一个基准转盘,之后将元素都放在转盘上,跟随转盘动. 2.画两个半圆,主要属性是border-top-right-radius: 250px; 像素值为长边的一半. 3.然后画4个圆,以基准转盘为父元素,按照下面黑色圆一样的思路再画另外一边白色的圆,最后再在两个中等的圆上画两个小圆. 4.设置定时器: //旋转角度 var deg = 0 //设置定时器,100毫秒动一次 var tid = s

  • C++俄罗斯方块游戏 无需图形库的俄罗斯方块

    本文实例为大家分享了C++俄罗斯方块游戏的具体实现代码,供大家参考,具体内容如下. #include<stdio.h> #include<stdlib.h> #include<windows.h> #include<time.h> #include<conio.h> #define MOD 28 #define SIZE_N 19 #define SIZE_M 12 int cur_x,cur_y; int score,mark,next,map

  • C语言字符串操作总结大全(超详细)

    1)字符串操作 strcpy(p, p1) 复制字符串 strncpy(p, p1, n) 复制指定长度字符串 strcat(p, p1) 附加字符串 strncat(p, p1, n) 附加指定长度字符串 strlen(p) 取字符串长度 strcmp(p, p1) 比较字符串 strcasecmp忽略大小写比较字符串strncmp(p, p1, n) 比较指定长度字符串 strchr(p, c) 在字符串中查找指定字符 strrchr(p, c) 在字符串中反向查找 strstr(p, p1

  • c语言10个经典小程序

    [程序1] 题目:有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 1.程序分析:可填在百位.十位.个位的数字都是1.2.3.4.组成所有的排列后再去 掉不满足条件的排列. 2.程序源代码: 复制代码 代码如下: main() { int i,j,k; printf("\n"); for(i=1;i<5;i++) /*以下为三重循环*/ for(j=1;j<5;j++) for (k=1;k<5;k++) { if (i!=k&&a

  • C语言程序设计50例(经典收藏)

    [程序1]题目:有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?1.程序分析:可填在百位.十位.个位的数字都是1.2.3.4.组成所有的排列后再去 掉不满足条件的排列. 2.程序源代码: 复制代码 代码如下: #include "stdio.h"#include "conio.h"main(){  int i,j,k;  printf("\n");  for(i=1;i<5;i++) /*以下为三重循环*/   

  • c语言字符数组与字符串的使用详解

    1.字符数组的定义与初始化字符数组的初始化,最容易理解的方式就是逐个字符赋给数组中各元素.char str[10]={ 'I',' ','a','m',' ','h','a','p','p','y'};即把10个字符分别赋给str[0]到str[9]10个元素如果花括号中提供的字符个数大于数组长度,则按语法错误处理:若小于数组长度,则只将这些字符数组中前面那些元素,其余的元素自动定为空字符(即 '\0' ). 2.字符数组与字符串在c语言中,将字符串作为字符数组来处理.(c++中不是)在实际应用

  • 利用C语言的Cairo图形库绘制太极图实例教程

    前言 可能许多人对直接用C语言绘图仍然停留在Turbo C的graphics.h年代,或许也有教育老化的原因,毕竟曾经的经典早已成往事,与其想尽各种办法寻找与其兼容的图形库,不如顺势拥抱灿烂的明天.Cario(http://cairographics.org/)是一个非常出色的2D图形库,著名的GTK+3.0完全采用Cario作为绘图引擎,由此可见它的强大和吸引力. Cario支持X Window,Quartz,Win32,image.buffers,PostScript,PDF和SVG文件等多

  • asp.net实现C#绘制太极图的方法

    本文实例讲述了asp.net实现C#绘制太极图的方法.分享给大家供大家参考.具体如下: 成品图如下所示: html页面: 注意设置: 复制代码 代码如下: ContentType="Image/Jpeg" 复制代码 代码如下: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="TaiJiTu.aspx.cs" Inherits="TaiJiTu&qu

  • C语言文件操作函数大全(超详细)

    fopen(打开文件)相关函数 open,fclose表头文件 #include<stdio.h>定义函数 FILE * fopen(const char * path,const char * mode);函数说明 参数path字符串包含欲打开的文件路径及文件名,参数mode字符串则代表着流形态.mode有下列几种形态字符串:r 打开只读文件,该文件必须存在.r+ 打开可读写的文件,该文件必须存在.w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失.若文件不存在则建立该文件.w

随机推荐