編輯:關於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 實現太極的實例代碼,有興趣朋友可以參考下,謝謝大家對本站的支持!
android開發教程之wifi開發示例
1、 WIFI網卡的狀態WIFI網卡的狀態信息都以整型變量的形式存放在 android.net.wifi.WifiManager 類中,有以下狀態:WIFI_STATE_
android:自定義HorizontalScrollView實現qq側滑菜單
今天看了鴻洋_大神在慕課網講的qq5.0側滑菜單。學了不少的知識,同時也佩服鴻洋_大神思路的清晰。看了教程課下也自己實現了一下。代碼幾乎完全相同 別噴我啊。。沒辦法 o(
Android中解析網絡請求的URL
最近正在做Android網絡應用的開發,使用了android網絡請求方面的知識,現在向大家介紹網絡請求方面的知識,我們知道android中向服務器端發送一個請求,(這就是
打造一個Android 3D立體旋轉容器
1.概述回到正題,這次帶來的效果,是一個Android 的3D立體旋轉的效果。當然靈感的來源,來自早些時間微博上看到的效果圖。非常酷有木有!作為程序猿我當然要把它加入我的
二、VR全景圖 ---- Android VR視頻/Google VR for Android /VR Pano/VR Video
SimpleVrPanorama其實這篇應該寫SimpleVrPanor