官术网_书友最值得收藏!

5.3 事件處理模型

在圖形用戶界面的開發中,有兩個非常重要的內容:一個是界面布局,另一個是控件的事件處理。在Android中,事件處理秉承了JavaSE圖形用戶界面的處理方式和風格。

Android在事件處理的過程中,主要涉及三個概念:

? 事件源:事件發生的場所,通常就是各個控件,例如按鈕Button、文本框EditText和活動等。

? 事件:用戶在界面上的操作的描述,可以封裝成為一個類的形式出現,例如鍵盤操作的事件類是KeyEvent,觸摸屏的移動事件類是MotionEvent。與JavaSE圖形界面不一樣的是并非所有的事件都被封裝成為一個類,例如Button單擊事件就沒有封裝成為一個類的形式。

? 事件處理者:接收事件對象并對其進行處理的對象,事件處理一般是一個實現某些特定接口類創建的對象。

事件源、事件和事件處理者之間是如何運作的?例如:圖5-3所示的LabelButton實例,當單擊OK按鈕時,將Label標簽內容修改為HelloWorld,那么這里的OK按鈕就是事件源,單擊就是事件,處理“將Label標簽修改為HelloWorld”的對象(或程序代碼)被稱為事件處理者。

一個類(或程序代碼)能夠成為事件處理者,要求有兩個前提:一是要求實現特定接口,LabelButton實例OK按鈕事件處理者要求實現android.view.View.OnClickListener接口;二是事件處理者必須在事件源上注冊。

提示 事件處理者由于實現XXXListener接口,因此也稱為事件監聽器。本書以后將事件處理者統一稱為事件監聽器。

具體的事件處理代碼有很多種模型,下面會一一介紹。

5.3.1 活動作為事件監聽器

在這種事件處理模型中,事件監聽器是當前活動(Activity),活動實現android.view. View.OnClickListener接口。

下面以LabelButton實例為例介紹這種事件處理模型。LabelButton中的MainActivity. java代碼如下:

        public class MainActivity extends AppCompatActivity implements View.OnClickListener{     ①
            @Override
            protected void onCreate(Bundle savedInstanceState){
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                //通過id獲得OK按鈕對象
                Button btnOK =(Button) findViewById(R.id.button);                                ②
                //注冊事件監聽器 
                btnOK.setOnClickListener(this);                                                  ③
            }

            /*
              * 實現View.OnClickListener接口方法
              */
              @Override
              public void onClick(View view){                                                    ④
                TextView text =(TextView) findViewById(R.id.textView);                           ⑤
                text.setText("HelloWorld");
              }
        }

當前界面的MainActivity實現View.OnClickListener接口,見代碼第①行。代碼第④行的onClick(View view)方法是實現View.OnClickListener接口所要求的方法,參數view是View類型,事實上該參數就是事件源Button對象。

代碼第③行是通過Button的setOnClickListener(View.OnClickListener listener)方法注冊事件監聽器為this,即MainActivity。

代碼第②行和第⑤行是通過id獲得控件對象,這些id都是布局文件activity_main.xml中聲明的控件id屬性。

布局文件activity_main.xml代碼如下:

        <?xml version="1.0" encoding="utf-8"?>
        <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:paddingBottom="@dimen/activity_vertical_margin"
          android:paddingLeft="@dimen/activity_horizontal_margin"
          android:paddingRight="@dimen/activity_horizontal_margin"
          android:paddingTop="@dimen/activity_vertical_margin"
          tools:context="com.a51work6.labelbutton.MainActivity">

          <TextView
              android:id="@+id/textView"                                           ①
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_alignParentTop="true"
              android:layout_centerHorizontal="true"
              android:layout_marginTop="59dp"
              android:text="Label"
              android:textSize="18sp"/>
          <Button
              android:id="@+id/button"                                             ②
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_below="@+id/textView"
              android:layout_centerHorizontal="true"
              android:layout_marginTop="49dp"
              android:text="OK"/>
        </RelativeLayout>

在布局文件activity_main.xml中,代碼第①行是聲明TextView(標簽)控件id為textView,代碼第②行是聲明Button控件的id為button。

? 屬性android:id="@+id/Button01"是Button按鈕的id,通過id可以找到此按鈕對象。

? 屬性android:layout_width="wrap_content"是設置寬度。

? 屬性android:layout_height ="wrap_content"是設置高度。

其中,寬和高都可以是wrap_content(適合文本大小)值,也可以是fill_parent(根據屏幕大小占滿)值,或是match_parent(匹配父容器大小)值,還可以是具體數字,例如200px。數字的單位可以是以下幾類:

? px:像素屏幕上的點。

? dp:與密度無關的像素,是一種基于屏幕密度的抽象單位。在每英寸160點的顯示器上,1dp = 1px;在大于160點的顯示器上可能增大。

? dip:與dp相同。

? sp:與刻度無關的像素,是與dp類似,但是可以根據用戶的字體大小首選項進行縮放等。

5.3.2 內部類事件監聽器

在這種事件處理模型中,事件監聽器是活動(Activity)類中聲明的內部類,該內部類也要求實現android.view.View.OnClickListener接口。

下面以LabelButton實例為例介紹這種事件處理模型。LabelButton中MainActivity. java代碼如下:

        public class MainActivity extends AppCompatActivity{

            @Override
            protected void onCreate(Bundle savedInstanceState){
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                //通過id獲得OK按鈕對象
                Button btnOK =(Button) findViewById(R.id.button);                           ①
                //注冊事件監聽器
                btnOK.setOnClickListener(new ButtonOKOnClickListener());                    ②
          }

          class ButtonOKOnClickListener implements View.OnClickListener{                    ③
              /*
                * 實現View.OnClickListener接口方法
                */
              @Override
              public void onClick(View view){
                  TextView text =(TextView) findViewById(R.id.textView);                    ④
                  text.setText("HelloWorld");
              }
          }

      }

代碼第③行是實現android.view.View.OnClickListener接口的內部類ButtonOKOn-ClickListener,因此代碼第②行注冊事件監聽器時候,需要實例化ButtonOKOnClickListener。

注意 任何實現android.view.View.OnClickListener的接口類,都可以成為Button事件監聽器,無論它是內部類還是外部類。但是需要注意:如果外部類實現接口時,外部類無法訪問活動(Activity)中的視圖,所以代碼第①行和第④行無法使用findViewById方法,findViewById方法是在Activity或View類中定義的。

5.3.3 匿名內部類事件監聽器

既然內部類很適合作為事件處理模型,那么內部類的一個特例匿名內部類是否也適合事件處理呢?事實上,在Android中事件處理時經常使用匿名內部類,包括官方的很多源代碼都采用匿名內部類的方式。

下面以LabelButton實例為例介紹這種事件處理模型。LabelButton中的MainActivity. java代碼如下:

        public class MainActivity extends AppCompatActivity{

            @Override
            protected void onCreate(Bundle savedInstanceState){
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                //通過id獲得OK按鈕對象
                Button btnOK =(Button) findViewById(R.id.button);
                //注冊事件監聽器
                btnOK.setOnClickListener(new View.OnClickListener(){                       ①
                    /*
                    * 實現View.OnClickListener接口方法
                    */
                    @Override
                    public void onClick(View v){
                      TextView text =(TextView) findViewById(R.id.textView);
                      text.setText("HelloWorld");
                  }
              });                                                                          ②
          }

      }

上述代碼第①行~第②行是注冊事件監聽,其中new View.OnClickListener(){…}是典型的Java匿名內部類的寫法。

提示 匿名內部類就是在使用接口(或者抽象類)的時候,直接給出這個接口(或者抽象類)實現。在Java中,接口(或者抽象類)是不能實例化的,實例化的是它們的實現類。匿名內部類的優點是:編譯之后代碼緊湊,可以在一定程度上減少字節碼文件長度,提高虛擬機的加載速度,從而提高運行速度。它的缺點是:代碼可讀性差。

縱觀三種事件處理模型,各有利弊,用戶可以根據自己的喜好來選擇,在實際的應用開發過程中,事件處理情況會更加復雜,同一個事件源上會有多個不同事件,因此有的時候不是單一的一種處理模型,而是多種模型的結合。

主站蜘蛛池模板: 凤冈县| 临漳县| 白水县| 图片| 故城县| 潜山县| 邛崃市| 铜梁县| 灵丘县| 封丘县| 尚志市| 齐齐哈尔市| 花莲县| 日照市| 武穴市| 贞丰县| 宜君县| 米泉市| 黄龙县| 黔西县| 徐闻县| 烟台市| 汶川县| 阿坝县| 珠海市| 高邮市| 台安县| 西安市| 依安县| 元谋县| 黎平县| 江西省| 榆林市| 历史| 祁东县| 淮安市| 荥经县| 洛川县| 新兴县| 油尖旺区| 珠海市|