登录 立即注册
安币:

安卓巴士 - 安卓开发 - Android开发 - 安卓 - 移动互联网门户

查看: 5470415|回复: 689

Android软件开发之盘点自定义View界面大合集(二)

  [复制链接]

249

主题

278

帖子

17

安币

初级码农

Rank: 1

发表于 2011-9-2 19:23:37 | 显示全部楼层 |阅读模式
自定义View界面大合集
今天我用自己写的一个Demo 和大家详细介绍一个Android中自定义View中的使用与绘制技巧。

1.自定义view绘制字符串
      
       相信在实际开发过程中必然很多地方都须要用到系统字 为什么会用到系统字? 方便 省内存 我相信做过J2ME游戏开发的朋友应该深知内存有多么多么重要  而且使用它还可以带来一个更重要的好处就是很方便的可以实现多国语言的切换 笔者现在在正在做的一个产品就是可以多语言切换的软件  有英语 繁体中文 等等 设想如果使用图片字的话那每个语言都须要出一套图,我用一个例子简单介绍一下绘制字符串。
  1. package cn.m15.xys;

  2. import android.app.Activity;
  3. import android.content.Context;
  4. import android.graphics.Canvas;
  5. import android.graphics.Color;
  6. import android.graphics.Paint;
  7. import android.graphics.Paint.FontMetrics;
  8. import android.os.Bundle;
  9. import android.view.Display;
  10. import android.view.View;

  11. public class Font extends Activity {
  12.     public int mScreenWidth = 0;
  13.     public int mScreenHeight = 0;
  14.     @Override
  15.     protected void onCreate(Bundle savedInstanceState) {
  16.         setContentView(new FontView(this));
  17.         // 获取屏幕宽高
  18.         Display display = getWindowManager().getDefaultDisplay();
  19.         mScreenWidth  = display.getWidth();
  20.         mScreenHeight = display.getHeight();
  21.         super.onCreate(savedInstanceState);

  22.     }

  23.     class FontView extends View {
  24.         public final static String STR_WIDTH = "获取字符串宽为:";
  25.         public final static String STR_HEIGHT = "获取字体高度为:";
  26.         Paint mPaint = null;
  27.         
  28.         public FontView(Context context) {
  29.             super(context);
  30.             mPaint = new Paint();
  31.         }

  32.         @Override
  33.         protected void onDraw(Canvas canvas) {
  34.             //设置字符串颜色
  35.             mPaint.setColor(Color.WHITE);
  36.             canvas.drawText("当前屏幕宽" + mScreenWidth, 0, 30, mPaint);
  37.             canvas.drawText("当前屏幕高"+ mScreenHeight, 0, 60, mPaint);
  38.             //设置字体大小
  39.             mPaint.setColor(Color.RED);
  40.             mPaint.setTextSize(18);
  41.             canvas.drawText("字体大小为18", 0, 90, mPaint);
  42.             //消除字体锯齿
  43.             mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
  44.             canvas.drawText("消除字体锯齿后", 0, 120, mPaint);
  45.             //获取字符串宽度
  46.             canvas.drawText(STR_WIDTH + getStringWidth(STR_WIDTH), 0, 150, mPaint);
  47.             //获取字体高度
  48.             canvas.drawText(STR_HEIGHT + getFontHeight(), 0, 180, mPaint);
  49.             //从string.xml读取字符串绘制
  50.             mPaint.setColor(Color.YELLOW);
  51.             canvas.drawText(getResources().getString(R.string.string_font), 0, 210, mPaint);
  52.             super.onDraw(canvas);
  53.         }
  54.         
  55.         /**
  56.          * 获取字符串宽
  57.          * @param str
  58.          * @return
  59.          */
  60.         private int getStringWidth(String str) {
  61.             return (int) mPaint.measureText(STR_WIDTH);
  62.         }
  63.         /*
  64.          * 获取字体高度
  65.          */
  66.         private int getFontHeight() {
  67.             FontMetrics fm = mPaint.getFontMetrics();
  68.             return (int)Math.ceil(fm.descent - fm.top) + 2;
  69.         }
  70.     }
  71. }
复制代码
2.绘制无规则几何图形

        绘制无规则几何图形似乎在实际工作中很少可以用到 原因是用程序去绘制图形即使在精准再好看也不会有美术出的图片好看 但是使用程序绘制图形作为学习来说却是基础中的基础,所以建议大家都看一看。
  1. package cn.m15.xys;

  2. import android.app.Activity;
  3. import android.content.Context;
  4. import android.graphics.Canvas;
  5. import android.graphics.Color;
  6. import android.graphics.Paint;
  7. import android.graphics.Path;
  8. import android.graphics.RectF;
  9. import android.os.Bundle;
  10. import android.view.View;

  11. public class Geometry extends Activity {
  12.     public int mScreenWidth = 0;
  13.     public int mScreenHeight = 0;

  14.     @Override
  15.     protected void onCreate(Bundle savedInstanceState) {
  16.         setContentView(new GeometryView(this));
  17.         super.onCreate(savedInstanceState);

  18.     }

  19.     class GeometryView extends View {
  20.         Paint mPaint = null;

  21.         public GeometryView(Context context) {
  22.             super(context);
  23.             mPaint = new Paint();
  24.             mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
  25.         }

  26.         @Override
  27.         protected void onDraw(Canvas canvas) {
  28.             super.onDraw(canvas);
  29.         
  30.             //设置画布颜色 也就是背景颜色
  31.             canvas.drawColor(Color.WHITE);
  32.            
  33.             mPaint.setColor(Color.BLACK);
  34.             canvas.drawText("绘制无规则几何图形喔!!!", 150, 30, mPaint);
  35.             
  36.             //绘制一条线
  37.             mPaint.setColor(Color.BLACK);
  38.             mPaint.setStrokeWidth(4);
  39.             canvas.drawLine(0, 0, 100, 100, mPaint);
  40.             
  41.             //绘制一个矩形
  42.             mPaint.setColor(Color.YELLOW);
  43.             canvas.drawRect(0, 120, 100, 200, mPaint);
  44.             
  45.             //绘制一个圆形
  46.             mPaint.setColor(Color.BLUE);
  47.             canvas.drawCircle(80, 300, 50, mPaint);
  48.             
  49.             //绘制一个椭圆
  50.             mPaint.setColor(Color.CYAN);
  51.             canvas.drawOval(new RectF(300,370,120,100), mPaint);
  52.             
  53.             //绘制多边形
  54.             mPaint.setColor(Color.BLACK);
  55.             Path path = new Path();
  56.             path.moveTo(150+5 , 400 -50);
  57.             path.lineTo(150+45, 400 - 50);
  58.             path.lineTo(150+30, 460 - 50);
  59.             path.lineTo(150+20, 460 - 50);
  60.             path.close();
  61.             canvas.drawPath(path, mPaint);
  62.             
  63.         }
  64.     }
  65. }
复制代码
3.图片的绘制以及旋转缩放的实现


        在这点上Android 确实比J2ME 强大很多  手机游戏开发最痛苦的是什么?? 是游戏引擎的开发,但是工程师会把大部分时间浪费在对坐标上,如果写引擎的时候没有把自适应考虑周全后期会非常痛苦,现在手机屏幕分辨率是各式各样 内存大小也是各式各样 所以可见自适应屏幕算法有多么的重要。

  1. package cn.m15.xys;

  2. import android.app.Activity;
  3. import android.content.Context;
  4. import android.graphics.Bitmap;
  5. import android.graphics.BitmapFactory;
  6. import android.graphics.Canvas;
  7. import android.graphics.Matrix;
  8. import android.graphics.Paint;
  9. import android.os.Bundle;
  10. import android.view.View;
  11. import android.view.View.OnClickListener;
  12. import android.widget.Button;
  13. import android.widget.LinearLayout;

  14. public class Image extends Activity {
  15.     ImageView imageView = null;

  16.     @Override
  17.     protected void onCreate(Bundle savedInstanceState) {
  18.         imageView = new ImageView(this);
  19.         setContentView(R.layout.image);
  20.         LinearLayout ll = (LinearLayout) findViewById(R.id.iamgeid);
  21.         ll.addView(imageView);
  22.         // 向左移动
  23.         Button botton0 = (Button) findViewById(R.id.buttonLeft);
  24.         botton0.setOnClickListener(new OnClickListener() {
  25.             @Override
  26.             public void onClick(View arg0) {
  27.                 imageView.setPosLeft();
  28.             }
  29.         });

  30.         // 向右移动
  31.         Button botton1 = (Button) findViewById(R.id.buttonRight);
  32.         botton1.setOnClickListener(new OnClickListener() {
  33.             @Override
  34.             public void onClick(View arg0) {
  35.                 imageView.setPosRight();
  36.             }
  37.         });
  38.         // 左旋转
  39.         Button botton2 = (Button) findViewById(R.id.buttonRotationLeft);
  40.         botton2.setOnClickListener(new OnClickListener() {
  41.             @Override
  42.             public void onClick(View arg0) {
  43.                 imageView.setRotationLeft();
  44.             }
  45.         });

  46.         // 右旋转
  47.         Button botton3 = (Button) findViewById(R.id.buttonRotationRight);
  48.         botton3.setOnClickListener(new OnClickListener() {
  49.             @Override
  50.             public void onClick(View arg0) {
  51.                 imageView.setRotationRight();
  52.             }
  53.         });

  54.         // 缩小
  55.         Button botton4 = (Button) findViewById(R.id.buttonNarrow);
  56.         botton4.setOnClickListener(new OnClickListener() {

  57.             @Override
  58.             public void onClick(View arg0) {
  59.                 imageView.setNarrow();
  60.             }
  61.         });

  62.         // 放大
  63.         Button botton5 = (Button) findViewById(R.id.buttonEnlarge);
  64.         botton5.setOnClickListener(new OnClickListener() {

  65.             @Override
  66.             public void onClick(View arg0) {
  67.                 imageView.setEnlarge();
  68.             }
  69.         });

  70.         super.onCreate(savedInstanceState);

  71.     }

  72.     class ImageView extends View {
  73.         Paint mPaint = null;
  74.         Bitmap bitMap = null;
  75.         Bitmap bitMapDisplay = null;
  76.         int m_posX = 120;
  77.         int m_posY = 50;
  78.         int m_bitMapWidth = 0;
  79.         int m_bitMapHeight = 0;
  80.         Matrix mMatrix = null;
  81.         float mAngle = 0.0f;
  82.         float mScale = 1f;//1为原图的大小

  83.         public ImageView(Context context) {
  84.             super(context);
  85.             mPaint = new Paint();
  86.             mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
  87.             bitMap = BitmapFactory.decodeResource(this.getResources(),
  88.                     R.drawable.image);
  89.             bitMapDisplay = bitMap;
  90.             mMatrix = new Matrix();
  91.             // 获取图片宽高
  92.             m_bitMapWidth = bitMap.getWidth();
  93.             m_bitMapHeight = bitMap.getHeight();
  94.         }

  95.         // 向左移动
  96.         public void setPosLeft() {
  97.             m_posX -= 10;
  98.         }

  99.         // 向右移动
  100.         public void setPosRight() {
  101.             m_posX += 10;
  102.         }

  103.         // 向左旋转
  104.         public void setRotationLeft() {
  105.             mAngle--;
  106.             setAngle();
  107.         }

  108.         // 向右旋转
  109.         public void setRotationRight() {
  110.             mAngle++;
  111.             setAngle();
  112.         }

  113.         // 缩小图片
  114.         public void setNarrow() {
  115.             if (mScale > 0.5) {
  116.                 mScale -= 0.1;
  117.                 setScale();
  118.             }
  119.         }

  120.         // 放大图片
  121.         public void setEnlarge() {
  122.             if (mScale < 2) {
  123.                 mScale += 0.1;
  124.                 setScale();
  125.             }
  126.         }

  127.         // 设置缩放比例
  128.         public void setAngle() {
  129.             mMatrix.reset();
  130.             mMatrix.setRotate(mAngle);
  131.             bitMapDisplay = Bitmap.createBitmap(bitMap, 0, 0, m_bitMapWidth,
  132.                     m_bitMapHeight, mMatrix, true);
  133.         }

  134.         // 设置旋转比例
  135.         public void setScale() {
  136.             mMatrix.reset();
  137.             //float sx X轴缩放
  138.             //float sy Y轴缩放
  139.             mMatrix.postScale(mScale, mScale);
  140.             bitMapDisplay = Bitmap.createBitmap(bitMap, 0, 0, m_bitMapWidth,
  141.                     m_bitMapHeight, mMatrix, true);
  142.         }

  143.         @Override
  144.         protected void onDraw(Canvas canvas) {
  145.             super.onDraw(canvas);
  146.             canvas.drawBitmap(bitMapDisplay, m_posX, m_posY, mPaint);
  147.             invalidate();
  148.         }
  149.     }
  150. }
复制代码
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.         android:id="@+id/iamgeid"
  4.     android:orientation="vertical"
  5.     android:layout_width="fill_parent"
  6.     android:layout_height="fill_parent"
  7.     >
  8.         <Button android:id="@+id/buttonLeft"
  9.             android:layout_width="fill_parent" android:layout_height="wrap_content"
  10.             android:text="图片向左移动"
  11.             />
  12.         <Button android:id="@+id/buttonRight"
  13.             android:layout_width="fill_parent" android:layout_height="wrap_content"
  14.             android:text="图片向右移动"
  15.             />
  16.         <Button android:id="@+id/buttonRotationLeft"
  17.             android:layout_width="fill_parent" android:layout_height="wrap_content"
  18.             android:text="图片左旋转"
  19.             />
  20.         <Button android:id="@+id/buttonRotationRight"
  21.             android:layout_width="fill_parent" android:layout_height="wrap_content"
  22.             android:text="图片右旋转"
  23.             />
  24.         <Button android:id="@+id/buttonNarrow"
  25.             android:layout_width="fill_parent" android:layout_height="wrap_content"
  26.             android:text="图片缩小"
  27.             />
  28.         <Button android:id="@+id/buttonEnlarge"
  29.             android:layout_width="fill_parent" android:layout_height="wrap_content"
  30.             android:text="图片放大"
  31.             />
  32. </LinearLayout>
复制代码
4.播放frame动画


        做游戏的话播放动画可就是必不可少的元素 帧动画帧动画 顾名思义是一帧一帧的播放 。 实际在开发中为了节省内存美术会把人物的图片切成一小块一小块然后由程序根据编辑器生成的点把图片在拼接起来这样就可以做到用更少的图片去实现更多的动画效果因为不太方便介绍图片编辑器 这个demo我只给大家简单的介绍一下播放动画的原理 后期我会深入讲解。
              如图所示这个小人一直在行走 实际上是4张图片在来回切换 每张图片延迟500毫秒 后播下一张 以此类推。
  1. package cn.m15.xys;

  2. import android.app.Activity;
  3. import android.content.Context;
  4. import android.graphics.Bitmap;
  5. import android.graphics.BitmapFactory;
  6. import android.graphics.Canvas;
  7. import android.graphics.Color;
  8. import android.graphics.Paint;
  9. import android.os.Bundle;
  10. import android.view.View;

  11. public class FramAnimation extends Activity {
  12.     public final static int ANIM_COUNT = 4;

  13.     @Override
  14.     protected void onCreate(Bundle savedInstanceState) {
  15.         setContentView(new FramView(this));
  16.         super.onCreate(savedInstanceState);

  17.     }

  18.     class FramView extends View {
  19.         Bitmap[] bitmap = new Bitmap[ANIM_COUNT];
  20.         Bitmap display = null;
  21.         Paint paint = null;
  22.         long startTime = 0;
  23.         int playID = 0;

  24.         public FramView(Context context) {
  25.             super(context);
  26.             for (int i = 0; i < ANIM_COUNT; i++) {
  27.                 bitmap[i] = BitmapFactory.decodeResource(this.getResources(),
  28.                         R.drawable.hero_a + i);
  29.             }
  30.             display = bitmap[0];
  31.             paint = new Paint();
  32.             startTime = System.currentTimeMillis();
  33.         }

  34.         @Override
  35.         protected void onDraw(Canvas canvas) {
  36.             super.onDraw(canvas);
  37.             paint.setColor(Color.WHITE);
  38.             canvas.drawText("播放动画中...", 100, 30, paint);
  39.             long nowTime = System.currentTimeMillis();
  40.             if (nowTime - startTime >= 500) {
  41.                 startTime=nowTime;
  42.                 playID++;
  43.                 if (playID >= ANIM_COUNT) {
  44.                     playID = 0;
  45.                 }
  46.                 canvas.drawBitmap(bitmap[playID], 100, 100, paint);
  47.             }
  48.             invalidate();
  49.         }
  50.     }

  51. }
复制代码
最后如果你还是觉得我写的不够详细 看的不够爽 不要紧我把源代码的下载地址贴出来 欢迎大家一起讨论学习
游客,如果您要查看本帖隐藏内容请回复

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

点评

学习一下,东西还是挺不错的!  发表于 2013-1-31 15:21

0

主题

380

帖子

715

安币

代码手工艺人

Rank: 4

发表于 2011-9-3 20:20:49 | 显示全部楼层
学习了~!

4

主题

211

帖子

316

安币

攻城狮

Rank: 3Rank: 3

发表于 2011-9-5 10:05:19 | 显示全部楼层
顶顶顶顶顶顶顶顶顶顶顶顶顶顶

0

主题

6

帖子

13

安币

初级码农

Rank: 1

发表于 2011-9-6 23:04:23 | 显示全部楼层
发现很多教程都是雪松发布的,顶下。

0

主题

7

帖子

3

安币

初级码农

Rank: 1

发表于 2011-9-7 00:03:57 | 显示全部楼层
不错,下载看看。

14

主题

360

帖子

204

安币

攻城狮

Rank: 3Rank: 3

发表于 2011-9-7 12:04:46 | 显示全部楼层
谢谢你的分享,帮了很大的忙!Thank you very much

0

主题

6

帖子

8

安币

初级码农

Rank: 1

发表于 2011-9-7 16:32:15 | 显示全部楼层
好东西,八错八错啊

0

主题

72

帖子

69

安币

程序猿

Rank: 2

发表于 2011-9-9 10:19:54 | 显示全部楼层
感谢楼主分享啊!顶
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

站长推荐

通过邮件订阅最新安卓weekly信息
上一条 /4 下一条

下载安卓巴士客户端

全国最大的安卓开发者社区
联系我们
关闭
合作电话:
15618560077
Email:
805941275@qq.com
商务市场合作/投稿
问题反馈及帮助
联系我们

广告投放| 广东互联网违法和不良信息举报中心|中国互联网举报中心|下载客户端|申请友链|手机版|站点统计|安卓巴士 ( 粤ICP备15117877号 )

快速回复 返回顶部 返回列表