疯狂Android讲义(1a)-基于监听的事件处理-控制飞机移动

3.2.2、事件和事件监听器

实例:控制飞机(图片)移动,src包含两个Java文件:PlainView.java 和 PlaneGame.java。

1.PlainView.java:

/**
 *
 */
package org.crazyit.event;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.View;

public class PlaneView extends View
{
	public float currentX;
	public float currentY;
	Bitmap plane;<span style="color:#FF0000;">//<span style="background-color: rgb(255, 255, 51);">1</span>
	// 定义、并创建画笔
	Paint p = new Paint();<span style="color:#FF0000;">//<span style="background-color: rgb(255, 255, 102);">2</span>
	public PlaneView(Context context)
	{
		super(context);
		// 定义飞机图片<span style="color:#FF0000;">//<span style="background-color: rgb(255, 255, 102);">3</span>
		plane = BitmapFactory.decodeResource(context.getResources(),
				R.drawable.plane);              
                //将控件设置成可获取焦点状态,默认是无法获取焦点的,只有设置成true,才能获取控件的点击事件
                setFocusable(true);
         }
         @Overridepublic 
         void onDraw(Canvas canvas)<span style="color:#FF0000;">//<span style="background-color: rgb(255, 255, 102);">4</span>
         {
              super.onDraw(canvas);
              // 绘制飞机
              canvas.drawBitmap(plane, currentX, currentY, p);<span style="color:#FF0000;">//<span style="background-color: rgb(255, 255, 102);">5</span>
         }
}

 (1)(3)Bitmap和BitmapFactory: 

          Bitmap实例代表位图,BitmapFactory提供方法decodeResource(Resources res,int id)用于根据给定资源ID从指定资源中解析创建Bitmap对象。

(2)(4)(5)Android绘图基础:Canvas、Paint类:

          Android绘图应该继承View组件,并重写onDraw(Canvas canvas)方法。Canvas代表了“依附于”指定view的画布。

          Canvas有方法:Canvas.drawBitmap(Bitmap bitmap, float left, float top, Paint paint),作用是从指定点绘制位图。

1、View的派生类应该包含构造方法,否则报错:“Implicit super constructor View() is undefined for default constructor.”(没有构造方法)。

2、main.xml中ImageView的属性 android:scaleType="fitXY"

3、ImageView警告“ [Accessibility] Missing contentDescription attribute on image”。这是ADT 16.0的新特性,在一些没有文本显示的控件里,如imageView和imageButton等,ADT会提示你定义一个android:contentDescription属性,用来描述这个控件的作用。

4、setContentView():

2. PlaneGame.java:

package org.crazyit.event;

import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.view.Window;
import android.view.WindowManager;

public class PlaneGame extends Activity
{
	// 定义飞机的移动速度
	private int speed = 10;
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		// 去掉窗口标题
		requestWindowFeature(Window.FEATURE_NO_TITLE);<span style="color:#FF0000;">//1</span>
		// 全屏显示
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,<span style="color:#FF0000;">//2</span>
			WindowManager.LayoutParams.FLAG_FULLSCREEN);
		// 创建PlaneView组件
 		final PlaneView planeView = new PlaneView(this);
 		setContentView(planeView);
 		planeView.setBackgroundResource(R.drawable.back);
		// 获取窗口管理器
 		WindowManager windowManager = getWindowManager();//3
		Display display = windowManager.getDefaultDisplay();
		DisplayMetrics metrics = new DisplayMetrics();
		// 获得屏幕宽和高
		display.getMetrics(metrics);
		// 设置飞机的初始位置
		planeView.currentX = metrics.widthPixels / 2;
		planeView.currentY = metrics.heightPixels - 40;//4
		// 为draw组件键盘事件绑定监听器
		planeView.setOnKeyListener(new OnKeyListener()
		{
			@Override
			public boolean onKey(View source, int keyCode, KeyEvent event)
			{
				// 获取由哪个键触发的事件
				switch (event.getKeyCode())
				{
					// 控制飞机下移
					case KeyEvent.KEYCODE_S:
						planeView.currentY += speed;//5
						break;
					// 控制飞机上移
					case KeyEvent.KEYCODE_W:
						planeView.currentY -= speed;
						break;
					// 控制飞机左移
					case KeyEvent.KEYCODE_A:
						planeView.currentX -= speed;
						break;
					// 控制飞机右移
					case KeyEvent.KEYCODE_D:
						planeView.currentX += speed;
						break;
				}
				// 通知planeView组件重绘
				planeView.invalidate();
				return true;
			}
		});
	}
}
(1)(2):在setContentView之前调用。

(3):关于DisplayMetrics类的用法见 Android 中的DisplayMetrics类的用法 

(4):setContentView剖析

(5):在使用Java局部内部类或者匿名内部类时,若该类调用了所在方法的局部变量,则该局部变量必须使用final关键字来修饰,否则将会出现编译错误“Cannot refer to a non-final variable * inside an inner class defined in a different method”

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值