Android开发:从0到1 (清华开发者书库)
上QQ阅读APP看书,第一时间看更新

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是缩小声音键键编码。