5.4 屏幕上的事件处理
在Android系统中,屏幕是通过活动(Activity)管理的,一个活动相当于一个屏幕,那么屏幕上的事件处理就是活动的事件处理,活动是事件源,活动有触摸事件和键盘事件等。
屏幕事件是在Android应用中常用的事件,本节介绍屏幕中的触摸事件和键盘事件。
5.4.1 触摸事件
现在,智能手机设计的一个理念是:可触摸与大屏幕。Android系统支持触摸屏开发,触摸屏事件要通过运动事件(MotionEvent)接收信息,如果屏幕中触摸事件的事件源是活动,开发人员需要重写活动方法:
public boolean onTouchEvent(MotionEvent event)
onTouchEvent方法返回值是布尔类型,返回true表示已经处理了该事件,false表示还没有处理该事件。参数event是MotionEvent类型,MotionEvent是运动事件,通过MotionEvent的int getAction()方法可以获得触摸动作,触摸动作有三种,通过MotionEvent三个常量表示:
❏ MotionEvent.ACTION_UP。在屏幕上手指抬起。
❏ MotionEvent.ACTION_DOWN。在屏幕上手指按下。
❏ MotionEvent.ACTION_MOVE。在屏幕上手指移动。
另外,触摸点的坐标可以通过MotionEvent的getX()和getY()方法获得。
5.4.2 实例:屏幕触摸事件
图5-8是屏幕触摸事件实例,当手指在屏幕上按下、抬起和移动时候,手指的动作会显示在屏幕的标签(TextView)上,触摸点的坐标也会显示在屏幕的标签(TextView)。
图5-8 触摸事件实例
布局文件activity_main.xml代码如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/ apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView ① android:id="@+id/action" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp"/> <TextView ② android:id="@+id/postion" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp"/> </LinearLayout>
在布局文件中声明了两个标签(TextView),代码第①行的标签用来显示手指的动作,代码第②行的标签用来显示触摸点的位置坐标。
MainActivity.java代码如下:
public class MainActivity extends AppCompatActivity{ private TextView mAction; private TextView mPostion; @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mAction=(TextView) findViewById(R.id.action); mPostion=(TextView) findViewById(R.id.postion); } @Override public boolean onTouchEvent(MotionEvent event){ ① int action= event.getAction(); ② switch(action){ caseMotionEvent.ACTION_UP: ③ mAction.setText("手指抬起"); break; caseMotionEvent.ACTION_DOWN: ④ mAction.setText("手指按下"); break; caseMotionEvent.ACTION_MOVE: ⑤ mAction.setText("手指移动"); } float X = event.getX(); ⑥ float Y = event.getY(); ⑦ mPostion.setText("位置 =("+ X +", "+ Y +")"); return true; }
上述代码第①行是在活动中重写onTouchEvent方法,代码第②行是获得触摸动作。代码第③行是判断手指在屏幕上抬起,代码第④行是判断手指在屏幕上按下,代码第④行是判断手指在屏幕上移动。
代码⑥行是获得触摸点的X轴坐标,代码⑦行是获得触摸点的Y轴坐标。
5.4.3 键盘事件
能够响应键盘事件的事件源可以是视图(View及其子类),也可以是活动(即屏幕),无论是视图还是活动键盘响应事件的处理模式都是类似的。本节介绍键盘事件的响应。
响应键盘事件就是通过使用KeyEvent接收信息,如果事件源是活动的,需要重写下面的方法:
❏ boolean onKeyUp(int keyCode, KeyEvent event);
❏ boolean onKeyDown(int keyCode, KeyEvent event);
❏ boolean onKeyLongPress(int keyCode, KeyEvent event)。
这个几个方法返回值true表示已经处理了该事件,返回false表示还没有处理该事件。方法参数keyCode键的编码,event参数是KeyEvent类型,KeyEvent是键盘事件。KeyEven中定义了很多键编码常量,如KeyEvent.KEYCODE_A常量编码表示A键。
另外,通过KeyEven的int getAction()方法可以获得键盘动作,键盘动作有三种,通过KeyEven三个常量表示如下:
❏ KeyEven.ACTION_UP。键抬起。
❏ KeyEven.ACTION_DOWN。键按下。
❏ KeyEven.ACTION_MULTIPLE。多次重复键按下。
5.4.4 实例:改变图片的透明度
本例实现如图5-9所示的内容,通过键盘来控制屏幕上的一个图片的透明度,图片的透明度是通过图片的Alpha值描述的,Android中的Alpha值在0~255之间,0表示完全透明,255表示完全不透明。
图5-9 键盘事件实例
提示 用什么键来控制声音的大和小呢?目前新款的Android手机多采用“软键盘”设计,手机上的硬件键很少,但至少都有声音控制键(包括放大声音键和缩小声音键两个)和关机键,如图5-10(a)所示是在模拟器上的声音控制键,图5-10(b)是在nexus设备上的声音控制键。本例可以利用这两个声音控制键控制图片透明度。
图5-10 声音控制键
布局文件activity_main.xml代码如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView ① android:id="@+id/alphavalue" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"/> <ImageView ② android:id="@+id/image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@mipmap/image"/> </LinearLayout>
在布局文件中,代码第①行声明了一个标签(TextView)控件,代码第②行声明了一个(ImageView),用来显示图片。
public class MainActivity extends AppCompatActivity{ ... @Override public void onCreate(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mImage =(ImageView) findViewById(R.id.image); mAlphavalueText =(TextView) findViewById(R.id.alphavalue); mAlphavalue = 100; //透明度初始值100 mImage.setImageAlpha(mAlphavalue); //设置图片初始透明度 mAlphavalueText.setText("Alpha="+ mAlphavalue * 100/255 +"%"); ① } @Override public boolean onKeyDown(int keyCode, KeyEvent event){ ② switch(keyCode){ case KeyEvent.KEYCODE_VOLUME_UP: //放大声音键 ③ mAlphavalue += 20; break; case KeyEvent.KEYCODE_VOLUME_DOWN: //缩小声音键 ④ mAlphavalue -= 20; break; } if(mAlphavalue = 255){ mAlphavalue = 255; //透明度最大值255 } if(mAlphavalue = 0){ mAlphavalue = 0; //透明度最小值0 } mImage.setImageAlpha(mAlphavalue); mAlphavalueText.setText("Alpha="+ mAlphavalue * 100/255 +"%"); return super.onKeyDown(keyCode, event); } }
上述代码第①行是设置mAlphavalueText标签控件的内容,mAlphavalue* 100/255表达式可以计算出透明度的百分比。
代码第②行重写活动的onKeyDown(int keyCode, KeyEvent event)方法,同类方法还有很多,本例只关心键盘按下事件。代码第③行是判断是否放大声音键按下,KeyEvent. KEYCODE_VOLUME_UP是放大声音键键编码。代码第④行是判断是否缩小声音键按下,KeyEvent.KEYCODE_VOLUME_DOWN是缩小声音键键编码。