今天我用自己寫的一個Demo 和大家詳細介紹一個Android中自定義View中的使用與繪制技巧。
1.自定義view繪制字符串
相信在實際開發過程中必然很多地方都須要用到系統字 為什麼會用到系統字? 方便、省內存。我相信做過J2ME游戲開發的朋友應該深知內存有多麼多麼重要,而且使用它還可以帶來一個更重要的好處就是可以很方便的實現多國語言的切換。筆者現在在正在做的一個產品就是可以多語言切換的軟件,有英語、繁體中文等等。設想如果使用圖片字的話那每個語言都須要出一套圖,我用一個例子簡單介紹一下繪制字符串。
Java代碼
- package cn.m15.xys;
-
- import android.app.Activity;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.graphics.Paint.FontMetrics;
- import android.os.Bundle;
- import android.view.Display;
- import android.view.View;
-
- public class Font extends Activity {
- public int mScreenWidth = 0;
- public int mScreenHeight = 0;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- setContentView(new FontView(this));
- // 獲取屏幕寬高
- Display display = getWindowManager().getDefaultDisplay();
- mScreenWidth = display.getWidth();
- mScreenHeight = display.getHeight();
- super.onCreate(savedInstanceState);
-
- }
-
- class FontView extends View {
- public final static String STR_WIDTH = "獲取字符串寬為:";
- public final static String STR_HEIGHT = "獲取字體高度為:";
- Paint mPaint = null;
-
- public FontView(Context context) {
- super(context);
- mPaint = new Paint();
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- //設置字符串顏色
- mPaint.setColor(Color.WHITE);
- canvas.drawText("當前屏幕寬" + mScreenWidth, 0, 30, mPaint);
- canvas.drawText("當前屏幕高"+ mScreenHeight, 0, 60, mPaint);
- //設置字體大小
- mPaint.setColor(Color.RED);
- mPaint.setTextSize(18);
- canvas.drawText("字體大小為18", 0, 90, mPaint);
- //消除字體鋸齒
- mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
- canvas.drawText("消除字體鋸齒後", 0, 120, mPaint);
- //獲取字符串寬度
- canvas.drawText(STR_WIDTH + getStringWidth(STR_WIDTH), 0, 150, mPaint);
- //獲取字體高度
- canvas.drawText(STR_HEIGHT + getFontHeight(), 0, 180, mPaint);
- //從string.xml讀取字符串繪制
- mPaint.setColor(Color.YELLOW);
- canvas.drawText(getResources().getString(R.string.string_font), 0, 210, mPaint);
- super.onDraw(canvas);
- }
-
- /**
- * 獲取字符串寬
- * @param str
- * @return
- */
- private int getStringWidth(String str) {
- return (int) mPaint.measureText(STR_WIDTH);
- }
- /*
- * 獲取字體高度
- */
- private int getFontHeight() {
- FontMetrics fm = mPaint.getFontMetrics();
- return (int)Math.ceil(fm.descent - fm.top) + 2;
- }
- }
- }
2.繪制無規則幾何圖形
繪制無規則幾何圖形似乎在實際工作中很少可以用到 原因是用程序去繪制圖形即使在精准再好看也不會有美術出的圖片好看 但是使用程序繪制圖形作為學習來說卻是基礎中的基礎,所以建議大家都看一看。
Java代碼
- package cn.m15.xys;
-
- import android.app.Activity;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.graphics.Path;
- import android.graphics.RectF;
- import android.os.Bundle;
- import android.view.View;
-
- public class Geometry extends Activity {
- public int mScreenWidth = 0;
- public int mScreenHeight = 0;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- setContentView(new GeometryView(this));
- super.onCreate(savedInstanceState);
-
- }
-
- class GeometryView extends View {
- Paint mPaint = null;
-
- public GeometryView(Context context) {
- super(context);
- mPaint = new Paint();
- mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- //設置畫布顏色 也就是背景顏色
- canvas.drawColor(Color.WHITE);
-
- mPaint.setColor(Color.BLACK);
- canvas.drawText("繪制無規則幾何圖形喔!!!", 150, 30, mPaint);
-
- //繪制一條線
- mPaint.setColor(Color.BLACK);
- mPaint.setStrokeWidth(4);
- canvas.drawLine(0, 0, 100, 100, mPaint);
-
- //繪制一個矩形
- mPaint.setColor(Color.YELLOW);
- canvas.drawRect(0, 120, 100, 200, mPaint);
-
- //繪制一個圓形
- mPaint.setColor(Color.BLUE);
- canvas.drawCircle(80, 300, 50, mPaint);
-
- //繪制一個橢圓
- mPaint.setColor(Color.CYAN);
- canvas.drawOval(new RectF(300,370,120,100), mPaint);
-
- //繪制多邊形
- mPaint.setColor(Color.BLACK);
- Path path = new Path();
- path.moveTo(150+5 , 400 -50);
- path.lineTo(150+45, 400 - 50);
- path.lineTo(150+30, 460 - 50);
- path.lineTo(150+20, 460 - 50);
- path.close();
- canvas.drawPath(path, mPaint);
-
- }
- }
- }
3.圖片的繪制以及旋轉縮放的實現
在這點上Android 確實比J2ME 強大很多 手機游戲開發最痛苦的是什麼?? 是游戲引擎的開發,但是工程師會把大部分時間浪費在對坐標上,如果寫引擎的時候沒有把自適應考慮周全後期會非常痛苦,現在手機屏幕分辨率是各式各樣 內存大小也是各式各樣 所以可見自適應屏幕算法有多麼的重要。
Java代碼
- package cn.m15.xys;
-
- import android.app.Activity;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Canvas;
- import android.graphics.Matrix;
- import android.graphics.Paint;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.LinearLayout;
-
- public class Image extends Activity {
- ImageView imageView = null;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- imageView = new ImageView(this);
- setContentView(R.layout.image);
- LinearLayout ll = (LinearLayout) findViewById(R.id.iamgeid);
- ll.addView(imageView);
- // 向左移動
- Button botton0 = (Button) findViewById(R.id.buttonLeft);
- botton0.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- imageView.setPosLeft();
- }
- });
-
- // 向右移動
- Button botton1 = (Button) findViewById(R.id.buttonRight);
- botton1.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- imageView.setPosRight();
- }
- });
- // 左旋轉
- Button botton2 = (Button) findViewById(R.id.buttonRotationLeft);
- botton2.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- imageView.setRotationLeft();
- }
- });
-
- // 右旋轉
- Button botton3 = (Button) findViewById(R.id.buttonRotationRight);
- botton3.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View arg0) {
- imageView.setRotationRight();
- }
- });
-
- // 縮小
- Button botton4 = (Button) findViewById(R.id.buttonNarrow);
- botton4.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View arg0) {
- imageView.setNarrow();
- }
- });
-
- // 放大
- Button botton5 = (Button) findViewById(R.id.buttonEnlarge);
- botton5.setOnClickListener(new OnClickListener() {
-
- @Override
- public void onClick(View arg0) {
- imageView.setEnlarge();
- }
- });
-
- super.onCreate(savedInstanceState);
-
- }
-
- class ImageView extends View {
- Paint mPaint = null;
- Bitmap bitMap = null;
- Bitmap bitMapDisplay = null;
- int m_posX = 120;
- int m_posY = 50;
- int m_bitMapWidth = 0;
- int m_bitMapHeight = 0;
- Matrix mMatrix = null;
- float mAngle = 0.0f;
- float mScale = 1f;//1為原圖的大小
-
- public ImageView(Context context) {
- super(context);
- mPaint = new Paint();
- mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
- bitMap = BitmapFactory.decodeResource(this.getResources(),
- R.drawable.image);
- bitMapbitMapDisplay = bitMap;
- mMatrix = new Matrix();
- // 獲取圖片寬高
- m_bitMapWidth = bitMap.getWidth();
- m_bitMapHeight = bitMap.getHeight();
- }
-
- // 向左移動
- public void setPosLeft() {
- m_posX -= 10;
- }
-
- // 向右移動
- public void setPosRight() {
- m_posX += 10;
- }
-
- // 向左旋轉
- public void setRotationLeft() {
- mAngle--;
- setAngle();
- }
-
- // 向右旋轉
- public void setRotationRight() {
- mAngle++;
- setAngle();
- }
-
- // 縮小圖片
- public void setNarrow() {
- if (mScale > 0.5) {
- mScale -= 0.1;
- setScale();
- }
- }
-
- // 放大圖片
- public void setEnlarge() {
- if (mScale < 2) {
- mScale += 0.1;
- setScale();
- }
- }
-
- // 設置縮放比例
- public void setAngle() {
- mMatrix.reset();
- mMatrix.setRotate(mAngle);
- bitMapDisplay = Bitmap.createBitmap(bitMap, 0, 0, m_bitMapWidth,
- m_bitMapHeight, mMatrix, true);
- }
-
- // 設置旋轉比例
- public void setScale() {
- mMatrix.reset();
- //float sx X軸縮放
- //float sy Y軸縮放
- mMatrix.postScale(mScale, mScale);
- bitMapDisplay = Bitmap.createBitmap(bitMap, 0, 0, m_bitMapWidth,
- m_bitMapHeight, mMatrix, true);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- canvas.drawBitmap(bitMapDisplay, m_posX, m_posY, mPaint);
- invalidate();
- }
- }
- }
XML/HTML代碼
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/iamgeid"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <Button android:id="@+id/buttonLeft"
- android:layout_width="fill_parent" android:layout_height="wrap_content"
- android:text="圖片向左移動"
- />
- <Button android:id="@+id/buttonRight"
- android:layout_width="fill_parent" android:layout_height="wrap_content"
- android:text="圖片向右移動"
- />
- <Button android:id="@+id/buttonRotationLeft"
- android:layout_width="fill_parent" android:layout_height="wrap_content"
- android:text="圖片左旋轉"
- />
- <Button android:id="@+id/buttonRotationRight"
- android:layout_width="fill_parent" android:layout_height="wrap_content"
- android:text="圖片右旋轉"
- />
- <Button android:id="@+id/buttonNarrow"
- android:layout_width="fill_parent" android:layout_height="wrap_content"
- android:text="圖片縮小"
- />
- <Button android:id="@+id/buttonEnlarge"
- android:layout_width="fill_parent" android:layout_height="wrap_content"
- android:text="圖片放大"
- />
- </LinearLayout>
4.播放frame動畫
做游戲的話播放動畫可就是必不可少的元素 幀動畫幀動畫 顧名思義是一幀一幀的播放 。 實際在開發中為了節省內存美術會把人物的圖片切成一小塊一小塊然後由程序根據編輯器生成的點把圖片在拼接起來這樣就可以做到用更少的圖片去實現更多的動畫效果因為不太方便介紹圖片編輯器 這個demo我只給大家簡單的介紹一下播放動畫的原理 後期我會深入講解。
如圖所示這個小人一直在行走 實際上是4張圖片在來回切換 每張圖片延遲500毫秒 後播下一張 以此類推。
Java代碼
- package cn.m15.xys;
-
- import android.app.Activity;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.os.Bundle;
- import android.view.View;
-
- public class FramAnimation extends Activity {
- public final static int ANIM_COUNT = 4;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- setContentView(new FramView(this));
- super.onCreate(savedInstanceState);
-
- }
-
- class FramView extends View {
- Bitmap[] bitmap = new Bitmap[ANIM_COUNT];
- Bitmap display = null;
- Paint paint = null;
- long startTime = 0;
- int playID = 0;
-
- public FramView(Context context) {
- super(context);
- for (int i = 0; i < ANIM_COUNT; i++) {
- bitmap[i] = BitmapFactory.decodeResource(this.getResources(),
- R.drawable.hero_a + i);
- }
- display = bitmap[0];
- paint = new Paint();
- startTime = System.currentTimeMillis();
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
- paint.setColor(Color.WHITE);
- canvas.drawText("播放動畫中...", 100, 30, paint);
- long nowTime = System.currentTimeMillis();
- if (nowTime - startTime >= 500) {
- startTime=nowTime;
- playID++;
- if (playID >= ANIM_COUNT) {
- playID = 0;
- }
- canvas.drawBitmap(bitmap[playID], 100, 100, paint);
- }
- invalidate();
- }
- }
-
- }
源碼下載地址:http://download.csdn.net/source/3448152