//去除窗口标题

requestWindowFeature(Window.FEATURE_NO_TITLE);

//全屏显示

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

//获取窗口管理器

WindowManager windowManager = getWindowManager();

Display display = windowManager.getDefaultDisplay();

// 获取屏幕宽和高

int screenWidth = display.getWidth();

int screenHeight = display.getHeight();

下面这种方式:该游戏几乎不需要页面布局,直接使用PlaneView作为Activity显示的内容

final PlaneView planeView = new PlaneView(this);

setContentView(planeView);

publicclass PlaneView extends View

{

publicfloat currentX;

publicfloat currentY;

Bitmap plane;

public PlaneView(Context context)

{

super(context);

plane = BitmapFactory.decodeResource(context.getResources(), R.drawable.plane);

setFocusable(true);去掉这行点击没反应,这句什么情况下运用? }

@Override

publicvoid onDraw (Canvas canvas)

{

super.onDraw(canvas);

Paint p = new Paint();

canvas.drawBitmap(plane , currentX , currentY , p);

}

}

draw组件绑定键盘事件监听器

planeView.setOnKeyListener(new OnKeyListener()

{

publicboolean onKey(View source, int keyCode, KeyEvent event)

{

switch (event.getKeyCode())

{

case KeyEvent.KEYCODE_DPAD_DOWN:

planeView.currentY += speed;

break;

case KeyEvent.KEYCODE_DPAD_UP:

planeView.currentY -= speed;

break;

case KeyEvent.KEYCODE_DPAD_LEFT:

planeView.currentX -= speed;

break;

case KeyEvent.KEYCODE_DPAD_RIGHT:

planeView.currentX += speed;

break;

}

planeView.invalidate();

returntrue;

}

});

有些时候并未发现事件的踪迹,这是因为android为事件监听模型做了进一步简化:如果事件源触发的事件足够简单,事件里封装的信息比较有限,就无需封装事件对象,将事件对象直接传入事件监听器

但对于一些复杂的事件(如键盘按键事件,需要包含更多的信息,android会将事件信息封装成XXXEvent对象,并把对象作为参数传入事件监听器)

上述程序将事件信息封装成Event对象。调用KeyEvent(事件对象)getKeyCode()来获取触发事件的键。

在基于事件监听的处理模型中,事件监听器必须实现事件监听器接口,android为不同的界面组件提供了不同的监听器接口,这些接口通常以内部类的形式存在。以View为例,它包含了如下几个内部接口:

View.OnClickListener:单击事件的事件监听器必须实现的接口

View.OnCreateContextMenuListener:创建上下文菜单事件的事件监听器必须实现的接口

View.onFocusChangeListener:焦点改变事件的事件监听器必须实现的接口。

View.OnKeyListener :按键事件的事件监听器必须实现的接口。

View.OnLongClickListener:长单击事件的事件处理器必须实现的接口

View.OnTouchListener:触摸屏事件的事件监听器必须实现的接口。

普通的java程序里的方法由程序主动调用,事件处理器中的事件处理方法是由系统负责调用。

所谓事件监听器,其实就是实现了特定接口的java类得实例。实现事件监听器,通常有如下几种形式:

内部类形式:

外部类形式

activity本身作为事件监听器类:让activity本身实现监听器接口,并实现事件处理方法

匿名内部类形式:使用匿名内部类创建事件监听器对象。

内部类:

publicclass EventQs extends Activity

{

@Override

publicvoid onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

//获取应用程序中的bn按钮

Button bn = (Button)findViewById(R.id.bn);

//为按钮绑定事件监听器。

bn.setOnClickListener(new MyClickListener());

}

//定义一个单击事件的监听器

class MyClickListener implements View.OnClickListener

{

//实现监听器类必须实现的方法,该方法将会作为事件处理器

@Override

publicvoid onClick(View arg0)

{

EditText txt = (EditText)findViewById(R.id.txt);

txt.setText("bn按钮被单击了!");

}

}

}

外部类作为事件监听器类

这种做法比较少见,主要有以下两点原因:

1, 事件监听器通常属于特定GUI界面,定义成外部类不利于提高程序的内聚性

2, 外部类的事件监听器不能自由访问创建GUI界面的类中的组件,编程不够简洁。

但如果某个事件监听器确实被多个GUI界面所共享,而且主要是完成某种业务逻辑的实现,则可以考虑使用外部类形式。

例如:

publicclass SendSmsListener implements OnLongClickListener

{

private Activity act;

private EditText address;

private EditText content;

public SendSmsListener(Activity act, EditText address, EditText content)

{

this.act = act;

this.address = address;

this.content = content;

}

@Override

publicboolean onLongClick(View source)

{

String addressStr = address.getText().toString();

String contentStr = content.getText().toString();

SmsManager smsManager = SmsManager.getDefault();

PendingIntent sentIntent = PendingIntent.getBroadcast(act, 0,

new Intent(), 0);

smsManager.sendTextMessage(addressStr, null, contentStr

, sentIntent, null);

Toast.makeText(act, "ŷ", Toast.LENGTH_LONG).show();

returnfalse;

}

}

3, activity本身作为事件监听器

缺点是分工不明确,看起来比较怪异。

//实现事件监听器接口

publicclass ActivityListener extends Activity

implements OnClickListener

{

EditText show;

Button bn;

@Override

publicvoid onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

show = (EditText)findViewById(R.id.show);

bn = (Button)findViewById(R.id.bn);

//直接使用Activity作为事件监听器

bn.setOnClickListener(this);

}

//实现事件处理方法

@Override

public void onClick(View v)

{

// TODO Auto-generated method stub

show.setText("bn按钮被单击了!");

}

}

匿名内部类:
publicclass AnonymousListener extends Activity

{

EditText show;

Button bn;

@Override

publicvoid onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

show = (EditText)findViewById(R.id.show);

bn = (Button)findViewById(R.id.bn);

//直接使用Activity作为事件监听器

bn.setOnClickListener(new OnClickListener()

{

//实现事件处理方法

@Override

public void onClick(View v)

{

// TODO Auto-generated method stub

show.setText("bn按钮被单击了!");

}

});

}

}这是常用的,因为基本上监听器只会用一次

3.2.7

直接绑定到标签

直接在界面布局文件中为制定标签绑定事件处理方法。

对于很多android界面组件标签而言,它们都支持如onClick,onLongClick等属性,这种属性的属性值就是一个形如xxx(View source)的方法的方法名。

publicclass BingingTag extends Activity

{

@Override

publicvoid onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

}

//定义一个事件处理方法

//其中source参数代表事件源

publicvoid clickHandler(View source)

{

EditText show = (EditText)findViewById(R.id.show);

show.setText("bn按钮被单击了");

}

}

在布局文件中为Button按钮绑定了一个事件处理方法:clickHanlder,所以在对应的activity中要定义一个void clickHandler(View source)方法,该方法会负责处理该按钮上的单击事件。

3.3 基于回调的事件处理

如果说监听器是委派式,那么回调则恰好相反;对于回调的事件处理模型来说,事件源与事件监听器是统一的,或者说监听器消失了。当用户在GUI组件上激发某种事件时,组件自己特定的方法会负责处理该事件。

为了使用回调机制类处理GUI组件上所发生的事件,我们需要为组件提供相应的事件处理方法,而java是一种静态语言,无法为某个对象动态的添加方法,因此只能继承GUI组件类,并重写该类的事件处理方法来实现。

android为所有GUI组件都提供了一些事件处理的回调方法,以View为例,该类包含如下方法。

boolean onKeyDown(int keyCode,KeyEvent event):当用户在该组件按下某个按键时触发该方法。

boolean onKeyLongPress(int KeyCode,KeyEvent event):当用户在该组件上常按某个按键时触发该方法。

boolean onKeyShortcut(int KeyCode,KeyEvent event):当一个键盘快捷键事件发生时触发该方法。

boolean onKeyUp(int keyCode,KeyEvent event):当用户在该组件上松开某个按键时触发该方法

boolean onTouchEvent(MotionEvent event):当用户在该组件上触发触摸屏事件时触发该方法

boolean onTrackballEvent(MotionEvent event) 当用户在该组件上触发轨迹球屏事件时触发该方法。

publicclass CallbackHandler extends Activity

{

@Override

publicvoid onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

}

}

publicclass MyButton extends Button

{

public MyButton(Context context , AttributeSet set)

{

super(context , set);

// TODO Auto-generated constructor stub

}

@Override

publicboolean onKeyDown(int keyCode, KeyEvent event)

{

super.onKeyDown(keyCode , event);

Log.v("-crazyit.org-" , "the onKeyDown in MyButton");

//返回true,表明该事件不会向外扩散

returntrue;

}

}

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

<!-- 使用自定义View时应使用全限定类名 -->

<org.crazyit.event.MyButton

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="单击我"

/>

</LinearLayout>

布局文件中使用Mybutton组件,java程序无须为该按钮绑定事件监听器因为该按钮自己重写了onKeyDown()方法,这意味着该按钮将会自己处理相应的事件。

通过上面介绍不然发现:基于监听的事件处理模型来说,事件源和事件监听器是分离的,当事件源发生特定事件后,该事件交给事件监听器负责处理;对于回调事件处理模型来说,事件源和事件监听器是统一的,当事件源发生特定事件后,该事件还是由模型本身负责。

3.3.2 基于回调的事件传播

几乎所有基于回调的事件处理都有一个boolean类型的返回值,该返回值标识该处理方法是否能完全处理该事件:

1, 返回true,表明已处理不会传播出去

2, false ,表明未完全处理,会继续传播

对于基于回调的事件传播而言,某组件上的事情不仅激发该组件上的回调方法,也会激发该组件所在activity的回调方法只要能传播到该activity

publicclass MyButton extends Button

{

public MyButton(Context context , AttributeSet set)

{

super(context , set);

}

@Override

publicboolean onKeyDown(int keyCode, KeyEvent event)

{

super.onKeyDown(keyCode , event);

Log.v("-MyButton-" , "the onKeyDown in MyButton");

//返回false,表明并未完全处理该事件,该事件依然向外扩散

returnfalse;

}

}

publicclass Propagation extends Activity

{

@Override

publicvoid onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

Button bn = (Button)findViewById(R.id.bn);

//bn绑定事件监听器

bn.setOnKeyListener(new OnKeyListener()

{

@Override

publicboolean onKey(View source

, int keyCode, KeyEvent event)

{

//只处理按下键的事件

if (event.getAction() == KeyEvent.ACTION_DOWN)

{

Log.v("-Listener-" , "the onKeyDown in Listener");

}

// 返回false,表明该事件会向外传播

returnfalse;

}

});

}

//重写onKeyDown方法,该方法可监听它所包含的所有组件的按键被按下事件

@Override

publicboolean onKeyDown(int keyCode, KeyEvent event)

{

super.onKeyDown(keyCode , event);

Log.v("-Activity-" , "the onKeyDown in Activity");

//返回false,表明并未完全处理该事件,该事件依然向外扩散

returnfalse;

}

}

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

<!-- 使用自定义View时应使用全限定类名 -->

<org.crazyit.event.MyButton

android:id="@+id/bn"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="单击我"

/>

</LinearLayout>

最终的结果是

the onKeyDown in Listener

the onKeyDown in MyButton

the onKeyDown in Activity

最先触发的是绑定在按键上的监听器,接着触发该组件提供的事件回调方法,然后传播到该组件所在的activity,当将false改成true的时候就会停止传播。

更多相关文章

  1. Android中如何使用基于监听的事件处理(上)
  2. android调用NotificationManager.notify无效,通知栏不显示
  3. android隐藏以及显示软键盘以及不自动弹出键盘的方法
  4. Android(安卓)Keep screen on(保持屏幕唤醒)
  5. Android获取屏幕宽高的方法
  6. Android(安卓)平板电脑的判断方法
  7. Android(安卓)- View的绘制流程一(measure)
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. android 模拟器设置代理服务器
  2. Android活动文件夹
  3. Session 'XXX': Error Installing APK
  4. Android实现自定义listview上拉刷新下拉
  5. Android(安卓)如何下载文件并轻松显示进
  6. Android(安卓)初始化脚本语法解析
  7. AndroidArchitecture
  8. Android(安卓)GridView控件自定义
  9. 适配Android 6、7、8、9、10期间遇到的坑
  10. Android系统应用程序安装过程源码分析