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

2.2 屏幕中內(nèi)容的控制和響應(yīng)

Android屏幕中的內(nèi)容是android.view.View類的繼承者。按照通常的概念,這些View的繼承者可以稱為控件。對于屏幕中內(nèi)容(控件)的控制和響應(yīng)是GUI系統(tǒng)最基礎(chǔ)的內(nèi)容。

程序中,對于屏幕中內(nèi)容(控件)的控制和響應(yīng)的兩個使用要點為:

獲得控件句柄;

定制控件的行為;

在Android中,得到控件的句柄通常是由id屬性來指定的。在布局文件中,用于指定id的XML屬性為android:id。

findViewById()方法用于得到一個控件句柄,其參數(shù)為控件的id,方法如下所示:

        public View findViewById (int id)

findViewById()是View和Activity都具有的方法,對于View表示獲得其某個子控件句柄,對于Activity,表示獲得其中內(nèi)容視圖(ContentView)的某個子控件句柄。

定制控件的行為,通常需要使用View類中的SetOn{XXX}Listener()系列方法,設(shè)置的內(nèi)容也就是前面所述的android.view包中的幾個接口。這個方法可以在每一個繼承View控件中被調(diào)用。

2.2.1 基本響應(yīng)方法

本節(jié)介紹Android中的幾種基本的程序控制方法,要獲得的效果是通過兩個按鈕來控制一個文本框的文字和字體顏色,其運行結(jié)果如圖2-3所示。

圖2-3 控件事件的響應(yīng)運行結(jié)果

本例構(gòu)建一個應(yīng)用程序,TestEvent1是活動的名稱,res/layout目錄中的testevent.xml是界面布局文件。本例布局文件的代碼如下所示:

        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/screen"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical">
            <TextView android:id="@+id/text1"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_gravity="center"
              android:textSize="24sp"
              android:text="@string/text1" />
            <Button android:id="@+id/button1"
              android:layout_width="80sp"
              android:layout_height="wrap_content"
              android:layout_gravity="center"
              android:text="@string/red"/>
            <Button android:id="@+id/button2"
              android:layout_width="80sp"
              android:layout_height="wrap_content"
              android:layout_gravity="center"
              android:text="@string/green"/>
        </LinearLayout>

以上布局文件中定義了兩個按鈕和一個文本框,這個布局文件被活動設(shè)置為Vi e w后,顯示的內(nèi)容就如圖2-2所示,只是行為還沒有實現(xiàn)。

行為將在源代碼文件TestEvent1.java中實現(xiàn),這部分的代碼如下所示:

        import android.app.Activity;
        import android.os.Bundle;
        import android.graphics.Color;
        import android.widget.Button;
        import android.widget.TextView;
        import android.view.View;
        import android.view.View.OnClickListener;
        import android.util.Log;
        public class TestEvent1 extends Activity {
            private static final String TAG = "TestEvent1";
            public TestEvent1() {
            }
            @Override
            public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.testevent);
              final TextView Text = (TextView) findViewById(R.id.text1);   // 獲得句柄
              final Button Button1 = (Button) findViewById(R.id.button1);
              final Button Button2 = (Button) findViewById(R.id.button2);
              Button1.setOnClickListener(new OnClickListener() { // 實現(xiàn)行為功能
                  public void onClick(View v) {
                      Text.setTextColor(Color.RED);      // 設(shè)置文本和文本顏色為“紅”
                      Text.setText("RED");
                  }
              });
              Button2.setOnClickListener(new OnClickListener() {
                  public void onClick(View v) {
                      Text.setTextColor(Color.GREEN);    // 設(shè)置文本和文本顏色為“綠”
                      Text.setText("GREEN");
                  }
              });
            }
        }

在創(chuàng)建的過程中,通過findViewById()獲得各個屏幕上面的控件(控件)的背景,這里使用的R.id.button1等和布局文件中各個元素的id是對應(yīng)的。在布局文件中即使不寫android:id這一項也可以正常顯示,這一項的目的是在代碼中對其進行控制:通過Activity的findViewById()方法根據(jù)id獲得每一個控件的句柄,以View類型返回,可以轉(zhuǎn)換成實際的類型來使用。

Button控件的setOnClickListener()設(shè)置了其中的點擊行為,這個方法的參數(shù)實際上是一個View.OnClickListener類型的接口,這個接口需要被實現(xiàn)才能夠使用,因此在本例的設(shè)置中,實現(xiàn)了其中的onClick()方法。這樣即可在點擊的時候?qū)崿F(xiàn)相應(yīng)的功能,在點擊的方法中,將通過Te x t的句柄對其進行控制。

在獲取句柄時需要轉(zhuǎn)換成相應(yīng)的控件類型,findViewById()方法的參數(shù)是一個整數(shù),返回值是View類型。通過R.id.XXX找到布局文件中定義的ID,然后通過將基類View轉(zhuǎn)換成其實際的類獲得真正的句柄??丶D(zhuǎn)換類應(yīng)該和布局文件中描述的控件一致,如果轉(zhuǎn)換成這個類的祖先類,將會損失部分繼承者自身功能,如果轉(zhuǎn)換成非祖先類并調(diào)用其中的方法將會錯誤。

提示:在代碼中使用R.id.myid的時候,如果當(dāng)前包中根本沒有myid這個id,編譯將報錯。但是如果這個包中的其他布局文件中生成myid這個id,但當(dāng)前布局文件中沒有這個id,編譯不會報錯,運行時將會返回null,造成運行錯誤。

2.2.2 變化的響應(yīng)方法

在實現(xiàn)控件行為方面,除了上述的使用方法,根據(jù)Java的語法,還具有其他的實現(xiàn)方式。第二種響應(yīng)方法可以將不同控件的同一種行為聚集到一個方法的實現(xiàn)中;第三種響應(yīng)方法可以為一個控件單獨實現(xiàn)一個響應(yīng)。

1.第二種響應(yīng)方法:由Activity實現(xiàn)某接口

對控件的響應(yīng)可以由Activity類來實現(xiàn)某個Listener接口,完成其中的方法,然后將其設(shè)置為某個控件的監(jiān)聽者,以此得到對控件的響應(yīng)。

以下程序使用的是上述實現(xiàn)方式,在使用同樣的布局文件的情況下,本例使用的源代碼文件如下所示:

        import android.app.Activity;
        import android.os.Bundle;
        import android.graphics.Color;
        import android.widget.Button;
        import android.widget.TextView;
        import android.view.View;
        import android.view.View.OnClickListener;
        import android.util.Log;
        public class TestEvent2 extends Activity
                                  implements OnClickListener {      // 實現(xiàn)相關(guān)的接口
            private static final String TAG = "TestEvent2";
            private TextView mText;                                 // 保存控件類的引用
            private Button mButton1;
            private Button mButton2;
            public TestEvent2() {
            }
            @Override
            public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.testevent);
              mText = (TextView) findViewById(R.id.text1);
              mButton1 = (Button) findViewById(R.id.button1);
              mButton1.setOnClickListener(this);        // 設(shè)置監(jiān)聽者為TestEvent2
              mButton2 = (Button) findViewById(R.id.button2);
              mButton2.setOnClickListener(this);        // 設(shè)置監(jiān)聽者為TestEvent2
            }
            public void onClick(View v) {
              Log.v(TAG, "onClick()");
              switch(v.getId()){                         // 通過getId()區(qū)分不同的控件
                  case R.id.button1:
                      mText.setTextColor(Color.RED);      // 設(shè)置文本和文本顏色為“紅”
                      mText.setText("RED");
                      break;
                  case R.id.button2:
                      mText.setTextColor(Color.GREEN);    // 設(shè)置文本和文本顏色為“綠”
                      mText.setText("GREEN");
                      break;
                  default:
                      Log.v(TAG, "other");
                      break;
              }
            }
        }

這個例子的主要變化是讓活動實現(xiàn)了(implements)OnClickListener()這個接口,也就是需要實現(xiàn)其中的onClick()方法。然后通過setOnClickListener()將其設(shè)置到按鈕中的參數(shù)就是this,表示了當(dāng)前的活動。

通過以這種方式設(shè)置,如果程序中有多個控件需要設(shè)置,那么所設(shè)置的也都是一個方法。為了保證對不同控件有不同的處理,可以由onClick()方法的參數(shù)進行判斷,參數(shù)是一個View類型,通過getId()獲得它們的ID,使用switch…case分別進行處理。

在本例中,需要將文本框(TextView)句柄保存為類的成員(mText),這樣就可以在類的各個方法中都能獲得這個句柄進行處理。這和第一種方法是有區(qū)別的,因為第一個例子實現(xiàn)的接口和獲得的TextView在同一個方法中,因此不需要保存TextView的句柄,只需要使用final的局部變量即可。

2.第三種響應(yīng)方法:構(gòu)建一個類實現(xiàn)某接口

在響應(yīng)控件事件方面,一種最為直接的方法是:構(gòu)建一個類實現(xiàn)所需要的Listener接口,創(chuàng)建這個類的實例之后,將其設(shè)置到控件中。

以下為同樣功能的第三種實現(xiàn)方法,在布局文件相同的情況下,Java源代碼的內(nèi)容如下所示:

        package com.android.basicapp;
        import android.app.Activity;
        import android.os.Bundle;
        import android.graphics.Color;
        import android.widget.Button;
        import android.widget.TextView;
        import android.view.View;
        import android.view.View.OnClickListener;
        import android.util.Log;
        public class TestEvent3 extends Activity{
            private static final String TAG = "TestEvent3";
            private TextView mText;
            private Button1_OnClickListener mListener1 = new Button1_Listener();
            private Button2_OnClickListener mListener2 = new Button2_Listener();
            public TestEvent3() {
            }
            class Button1_Listener implements OnClickListener { // 接口的第一個實現(xiàn)
              public void onClick(View v) {
                      mText.setTextColor(Color.RED);     // 設(shè)置文本和文本顏色為“紅”
                      mText.setText("RED");
              }
            }
            class Button2_Listener implements OnClickListener {   // 接口的第一個實現(xiàn)
              public void onClick(View v) {
                      mText.setTextColor(Color.GREEN);              //設(shè)置文本和文本顏色為“綠”
                      mText.setText("GREEN");
              }
            }
            @Override
            public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.testevent);
              mText = (TextView) findViewById(R.id.text1);
              final Button mButton1 = (Button) findViewById(R.id.button1);
              final Button mButton2 = (Button) findViewById(R.id.button2);
              mButton1.setOnClickListener(mListener1);  // 設(shè)置監(jiān)聽者的類
              mButton2.setOnClickListener(mListener2);  // 設(shè)置監(jiān)聽者的類
            }
        }

本例通過定義實現(xiàn)活動類中的兩個子類,來實現(xiàn)View.OnClickListener這個接口,這種方式是一種最為直接的方式,即為不同的控件單獨實現(xiàn)它的相應(yīng)類。

使用這種實現(xiàn)方法,如果由一個類繼承若干個Listener接口,可以讓其實現(xiàn)多個不同的行為。實現(xiàn)同時點擊和長按事件的方法如下所示:

        class MyListener implements OnClickListener,OnLongClickListener {
            public void onClick(View v) {
              // ......點擊事件的實現(xiàn)
            }
            public boolean onLongClick(View v){
              // ......長按事件的實現(xiàn)
            }
        }

隨后可以調(diào)用setOnClickListener()和setOnLongClickListener()將這個監(jiān)聽者的實現(xiàn)設(shè)置到某個控件當(dāng)中。這種方式尤其適合一個控件需要定制多個行為,并且可能多個行為之間還有共同處理(例如,調(diào)用同一個方法)的場合。

2.2.3 控件響應(yīng)方法比較

以上列出了在Java代碼中對控件事件做出響應(yīng)的三種方法,比較這三種方法,分別具有以下的特點。

第一種方法利用Java的語法,將所有內(nèi)容都組織到一個方法當(dāng)中。這種方法雖然看似簡單,但是這種程序的結(jié)構(gòu)性并不好。

第二種方法將不同控件的同一種行為聚集到一個方法中:只需要實現(xiàn)一個接口中的方法,就可以為所有控件使用。

第三種方法可以將同一個控件的不同行為聚集到一個類當(dāng)中。如果構(gòu)建一個類讓其繼承多個Listener,并實現(xiàn)其中的方法,可以同時完成對多個行為的響應(yīng)。

在實際的應(yīng)用場景中,由于多個同類控件響應(yīng)同一種行為的情況比較多見,因此在Android應(yīng)用程序的實現(xiàn)中,第二種方法的使用比第三種方法多。

如果同一個布局中控件的id有所重復(fù),即多個控件使用相同的id,在這種情況下,第二種方法的switch…case將不太容易區(qū)分每個控件。這時可以考慮使用第三種方法,自己實現(xiàn)不同的類,在設(shè)置監(jiān)聽器的階段對不同控件做出區(qū)分。

主站蜘蛛池模板: 寿阳县| 阳朔县| 尤溪县| 元氏县| 紫阳县| 崇阳县| 东方市| 宾阳县| 平乡县| 横山县| 南宫市| 疏附县| 四子王旗| 武清区| 巨鹿县| 拜泉县| 南乐县| 曲水县| 东兰县| 抚顺市| 哈尔滨市| 宝丰县| 邛崃市| 榆林市| 昌吉市| 长宁县| 北辰区| 隆林| 衡阳市| 林州市| 诸暨市| 行唐县| 天台县| 海伦市| 花莲市| 罗平县| 中宁县| 大邑县| 屏南县| 石林| 健康|