1. 程式人生 > >Button點選事件的五種寫法

Button點選事件的五種寫法

操作環境

Project:ButtonTest
IDE:Android Studio2.1

學習了幾個月的Android,覺得有必要複習一下前面學過的知識,哪怕再簡單的知識也是可以溫故而知新的。就從最簡單的按鈕點選事件開始吧。我總結了五種不同的寫法,如下:

  1. 匿名內部類
  2. 使用View.onClickListener
  3. 使用onClick屬性
  4. 自定義單擊事件監聽類
  5. 使用外部類。

我在佈局上按照不同的寫法放置了五個按鈕,點選不同的按鈕,就會把按鈕上的文字傳遞到頂部的TextView。下面是整體的UI介面:

這裡寫圖片描述

這是我完成整個部落格之後的介面,由於我是邊寫邊執行邊截圖的,在下面你會看到按鈕是一個一個加上去的。

1. 匿名內部類

這個寫法用得非常多,只要呼叫setOnClickListener(),在裡面傳入匿名內部類就可以了使用介面中的onCLick方法了。

public class ButtonActivity extends AppCompatActivity {
    private Button button1;
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_button);
        textView = (TextView) findViewById(R.id.textView);
        button1 = (Button) findViewById(R.id.button1);
        button1.setOnClickListener(new
View.OnClickListener() { @Override public void onClick(View v) { textView.setText("匿名內部類"); } }); } }

完成效果
這裡寫圖片描述

2. 使用View.onClickListener 介面

我個人很喜歡這種寫法,只要讓Activity繼承View.OnClickListener介面,然後讓Button物件去呼叫setOnClickListener()方法,並在其中傳入this就可以了。在點選事件特別多的時候,這種寫法的優勢就出來了:在OnClick方法中使用switch語句,就可以在不同控制元件的的點選事件中來回切換,非常的簡潔和便利。

public class ButtonActivity extends AppCompatActivity implements View.OnClickListener{
    private Button button1,button2;
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_button);
        //初始化控制元件
        textView = (TextView) findViewById(R.id.textView);
        button1 = (Button) findViewById(R.id.button1);
        button2 = (Button) findViewById(R.id.button2);

        //1.匿名內部類
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textView.setText("匿名內部類");
            }
        });
        //2.使用View.onClickListener介面
        button2.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        textView.setText("使用View.onClickListener介面");
    }
}

這裡寫圖片描述

3.使用onClick屬性

這種寫法簡單到有點不可思議,它是五種方法中唯一沒有在程式碼中繼承View.onClickListener介面的,我們所要做的只是在xml檔案中新增onClick屬性:

android:onClick="buttonClick"

然後回到程式碼中寫上下面的方法,方法名稱就是你在OnClick屬性中名字。

    //3.使用onClick屬性
    public void buttonClick(View v){
        textView.setText("使用onClick屬性");

    }

完成效果
這裡寫圖片描述

如果你要設定的按鈕點選事件只有那麼一兩個,這種寫法無疑是非常省事的。但是如果你點選事件很多的話就要小心,因為不同按鈕的點選事件是根據OnClick中的內容確定的,所以在xml檔案中寫太多的OnClick屬性可能會弄混,到頭來你都不記得哪一個方法對應哪一個按鈕了。

那麼有沒有方法可以多個按鈕都同時使用這種寫法呢?答案是有的。你可以在多個Button的節點中使用OnClick屬性,比如android:onClick=”buttonClick”,這時你點選這些按鈕,呼叫的都是同一個buttonClick()方法。為了區分,這時候你就需要再給每一個按鈕設定資源id,然後通過switch語句進行判斷,寫法如下。

    public void buttonClick(View v){
        int id = v.getId();
        switch (id) {
        case R.id.bt1:
            System.out.println("按鈕1");
            break;
        case R.id.bt2:
            System.out.println("按鈕2");
            break;
        case R.id.bt3:
            System.out.println("按鈕3");
            break;

        }
    }

你可以自己設定多個按鈕,然後列印不同的日誌或者彈出不同的Toast來看看實現效果,這裡我就不實現了。

4.自定義單擊事件監聽類

自定義其實就是建立一個類,然後去繼承View.OnClickListener介面,然後去實現介面中的onClick()方法就可以了。

class MyClickListener implements View.OnClickListener{

        @Override
        public void onClick(View v) {
            textView.setText("自定義單擊事件監聽類");
        }
    }

然後初始化Button按鈕並呼叫setOnClickListener()方法,注意了,這裡傳進去的引數就是我們新建的類MyClickListener的匿名物件。

button4 = (Button) findViewById(R.id.button4);
button4.setOnClickListener(new MyClickListener());

這種寫法應該比較冷門,反正我目前都沒有使用過,畢竟要建立一個類看起來有點畫蛇添足。
完成效果
這裡寫圖片描述

5.使用外部類

第五種方法比較特別。它跟第四種很像,不同的是onClick()方法一共出現了兩次。那麼這有什麼用呢?我們來試一下就知道了。新建一個外部類OuterClass,自然我們也讓它繼承View.OnClickListener介面,同時也讓它列印一條log日誌,以便我們檢視它是否呼叫了:

    //5.使用外部類
    class OuterClassListener implements View.OnClickListener{
        @Override
        public void onClick(View v) {
            Log.d("Tag", "父類中的onClick方法");
        }
    }

接下來的寫法是不是有點眼熟?不錯,跟匿名內部類一樣,只不過這裡的onClick方法編譯器不會自動幫我們生成,需要我們自己動手新增。另外,要注意加上 super.onClick(v)這一句,表示呼叫父類中的onClick方法。

        //5.使用外部類
        button5 = (Button) findViewById(R.id.button5);
        button5.setOnClickListener(new OuterClassListener(){
            @Override
            public void onClick(View v) {
                super.onClick(v);
                textView.setText("使用外部類");
            }
        });

完成效果:
這裡寫圖片描述
執行之後,點選按鈕,除了我們預期中的TextView的文字發生變化之後,還列印了一條log日誌:
這裡寫圖片描述

這說明點選按鈕之後,父類和子類的onClick方法都呼叫了。那麼,這樣的寫法有什麼好處呢?這種寫法的好處在於當子類較多時,我們可以把子類的相同程式碼集中到父類中,這樣父類就可以批量實現你所需要的效果,避免了程式碼冗餘。

完整程式碼

最後貼上完整的程式碼吧。本人還在學習中,所以如果有錯誤的話還請大家多多指正。

activity_button.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    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.lin.mr.buttontest.ButtonActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="接收傳過來的文字"
        android:textSize="25sp" />

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="匿名內部類" />

    <Button
        android:layout_marginTop="10dp"
        android:id="@+id/button2"
        android:text="使用View.OnClickListener介面"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:onClick="buttonClick"
        android:layout_marginTop="10dp"
        android:id="@+id/button3"
        android:text="使用onClick屬性"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:layout_marginTop="10dp"
        android:id="@+id/button4"
        android:text="自定義單擊事件監聽類"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:layout_marginTop="10dp"
        android:id="@+id/button5"
        android:text="使用外部類"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

ButtonActivity

package com.lin.mr.buttontest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class ButtonActivity extends AppCompatActivity implements View.OnClickListener{
    private Button button1,button2,button4,button5;
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_button);
        //初始化控制元件
        textView = (TextView) findViewById(R.id.textView);
        button1 = (Button) findViewById(R.id.button1);
        button2 = (Button) findViewById(R.id.button2);
        button4 = (Button) findViewById(R.id.button4);


        button4.setOnClickListener(new MyClickListener());

        //5.使用外部類
        button5 = (Button) findViewById(R.id.button5);
        button5.setOnClickListener(new OuterClassListener(){
            @Override
            public void onClick(View v) {
                super.onClick(v);
                textView.setText("使用外部類");
            }
        });

        //1.匿名內部類
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textView.setText("匿名內部類");
            }
        });
        //2.使用View.onClickListener介面
        button2.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        textView.setText("使用View.onClickListener介面");
    }

    //3.使用onClick屬性
    public void buttonClick(View v){
        textView.setText("使用onClick屬性");

    }

    //4.自定義單擊事件監聽類
    class MyClickListener implements View.OnClickListener{

        @Override
        public void onClick(View v) {
            textView.setText("自定義單擊事件監聽類");
        }
    }

    //5.使用外部類
    class OuterClassListener implements View.OnClickListener{
        @Override
        public void onClick(View v) {
            Log.d("Tag", "父類中的onClick方法");
        }
    }
}

補充知識:OnClick()方法中的引數

寫了這麼多種點選事件的寫法之後,有沒有發現onClick()方法中總是需要傳入一個引數呢?這個引數是什麼呢?乍一看,這應該是View的一個物件。我們在學習第3種寫法(使用onClick屬性)時提到了switch語句:

    public void buttonClick(View v){
        int id = v.getId();
        switch (id) {
        case R.id.bt1:

            break;
        case R.id.bt2:

            break;
        case R.id.bt3:

            break;
        }
    }

注意到這一句:“int id = v.getId();”。v是View的物件,它通過getId()方法獲取到了Button的Id,然後將獲取到的id交給switch進行判斷,從而實現不同按鈕的點選事件。所以onClick()方法裡面的引數就是觸發點選方法執行的元件物件,在這裡,我們的元件毫無疑問就是Button按鈕了。