簡體   English   中英

Android:如何處理按鈕點擊

[英]Android: how to handle button click

在非 Java 和非 Android 領域擁有豐富的經驗,我正在學習 Android。

我對不同的領域有很多困惑,其中之一是如何處理按鈕點擊。 至少有 4 種方法 (!!!),它們在此處簡要列出

為了保持一致性,我將列出它們:

  1. 在活動中擁有View.OnClickListener類的成員,並將其分配給將在onCreate活動方法中處理onClick邏輯的實例。

  2. 在“onCreate”活動方法中創建“onClickListener”並使用 setOnClickListener 將其分配給按鈕

  3. 在活動本身中實現“onClickListener”並將“this”指定為按鈕的偵聽器。 如果 Activity 的按鈕很少,則應分析按鈕 ID 以針對正確的按鈕執行“onClick”處理程序

  4. 在實現“onClick”邏輯的活動上擁有公共方法並將其分配給活動 xml 聲明中的按鈕

問題 1:

這些都是方法,還有其他選擇嗎? (我不需要任何其他的,只是好奇)

對我來說,最直觀的方法是最新的:它需要輸入的代碼最少,而且可讀性最強(至少對我而言)。

不過,我沒有看到這種方法被廣泛使用。 使用它有什么缺點?

問題2:

每種方法的優缺點是什么? 請分享您的經驗或好的鏈接。

歡迎任何反饋!

PS 我已經嘗試使用谷歌搜索並找到有關此主題的內容,但我發現的唯一內容是描述“如何”做到這一點,而不是為什么它是好是壞。

問題1:不幸的是,您說最直觀的那個在Android中使用最少。 據我了解,您應該將 UI (XML) 和計算功能(Java 類文件)分開。 它還使調試更容易。 以這種方式閱讀和思考 Android imo 實際上要容易得多。

問題2:我認為主要使用的兩個是#2和#3。 我將使用 Button clickButton 作為示例。

2

是匿名類的形式。

Button clickButton = (Button) findViewById(R.id.clickButton);
clickButton.setOnClickListener( new OnClickListener() {
            
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                ***Do what you want with the click here***
            }
        });

這是我最喜歡的,因為它在使用 findViewById 設置按鈕變量的位置旁邊有 onClick 方法。 處理此 clickButton 按鈕視圖的所有內容都位於此處,這似乎非常整潔。

我的同事評論的一個缺點是,假設您有許多需要 onclick 偵聽器的視圖。 你可以看到你的 onCreate 會變得很長。 所以這就是他喜歡使用的原因:

3

假設您有 5 個點擊按鈕:

確保您的 Activity/Fragment 實現 OnClickListener

// in OnCreate

Button mClickButton1 = (Button)findViewById(R.id.clickButton1);
mClickButton1.setOnClickListener(this);
Button mClickButton2 = (Button)findViewById(R.id.clickButton2);
mClickButton2.setOnClickListener(this);
Button mClickButton3 = (Button)findViewById(R.id.clickButton3);
mClickButton3.setOnClickListener(this);
Button mClickButton4 = (Button)findViewById(R.id.clickButton4);
mClickButton4.setOnClickListener(this);
Button mClickButton5 = (Button)findViewById(R.id.clickButton5);
mClickButton5.setOnClickListener(this);


// somewhere else in your code

public void onClick(View v) {
    switch (v.getId()) {
        case  R.id.clickButton1: {
            // do something for button 1 click
            break;
        }

        case R.id.clickButton2: {
            // do something for button 2 click
            break;
        }

        //.... etc
    }
}

正如我的同事所解釋的那樣,這種方式在他看來更整潔,因為所有 onClick 計算都在一個地方處理,而不是擠滿 onCreate 方法。 但我看到的缺點是:

  1. 自己的看法,
  2. 並且任何其他可能位於 onCreate 中由 onClick 方法使用的對象都必須成為一個字段。

如果您想了解更多信息,請告訴我。 我沒有完全回答你的問題,因為這是一個很長的問題。 如果我找到一些網站,我會擴大我的答案,現在我只是提供一些經驗。

#1當布局上有未生成的按鈕(但顯然是靜態的)時,我經常使用最后一個。

如果您在實踐中和業務應用程序中使用它,請特別注意這里,因為當您使用像 ProGuard 這樣的源代碼混淆器時,您需要在您的活動中標記這些方法不被混淆。

要使用這種方法歸檔某種編譯時安全性,請查看Android Lint示例)。


#2所有方法的優缺點幾乎相同,教訓應該是:

使用對您來說最合適或最直觀的方式。

如果您必須將相同的OnClickListener分配給多個按鈕實例,請將其保存在類范圍 (#1) 中。 如果您需要一個簡單的 Button 偵聽器,請進行匿名實現:

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        // Take action.
    }
});

我傾向於不在活動中實現OnClickListener ,這會不時變得有點混亂(尤其是當您實現多個其他事件處理程序而沒有人知道this一切在做什么時)。

我更喜歡選項 4,但它對我來說很直觀,因為我在 Grails、Groovy 和 JavaFX 中做了太多工作。 視圖和控制器之間的“神奇”連接在所有方面都很常見。 為方法命名很重要:

在視圖中,將 onClick 方法添加到按鈕或其他小部件:

    android:clickable="true"
    android:onClick="onButtonClickCancel"

然后在類中,處理方法:

public void onButtonClickCancel(View view) {
    Toast.makeText(this, "Cancel pressed", Toast.LENGTH_LONG).show();
}

再次,清楚地命名方法,無論如何你應該做的事情,並且維護成為第二天性。

一大優勢是您現在可以為該方法編寫單元測試。 選項 1 可以做到這一點,但選項 2 和 3 更難。

最常用的方式是,匿名聲明

    Button send = (Button) findViewById(R.id.buttonSend);
    send.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // handle click
        }
    });

您也可以創建 View.OnClickListener 對象並稍后將其設置為按鈕,但您仍然需要覆蓋 onClick 方法,例如

View.OnClickListener listener = new View.OnClickListener(){
     @Override
        public void onClick(View v) {
            // handle click
        }
}   
Button send = (Button) findViewById(R.id.buttonSend);
send.setOnClickListener(listener);

當您的活動實現 OnClickListener 接口時,您必須在活動級別覆蓋 onClick(View v) 方法。 然后您可以將此活動作為按鈕的偵聽器,因為它已經實現了接口並覆蓋了 onClick() 方法

public class MyActivity extends Activity implements View.OnClickListener{


    @Override
    public void onClick(View v) {
        // handle click
    }


    @Override
    public void onCreate(Bundle b) {
        Button send = (Button) findViewById(R.id.buttonSend);
        send.setOnClickListener(this);
    }

}

(恕我直言)當多個按鈕具有相同的處理程序時使用的第 4 種方法,您可以在活動類中聲明一個方法並將此方法分配給 xml 布局中的多個按鈕,您也可以為一個按鈕創建一個方法,但在這種情況下我更喜歡在活動類中聲明處理程序。

選項 1 和 2 涉及使用內部類,這會使代碼變得混亂。 選項 2 有點混亂,因為每個按鈕都有一個偵聽器。 如果您的按鈕數量很少,這沒關系。 對於選項 4,我認為這將更難調試,因為您必須返回 xml 和 java 代碼。 當我必須處理多個按鈕點擊時,我個人使用選項 3。

我的示例,在 Android studio 2.1 中測試

在 xml 布局中定義按鈕

<Button
    android:id="@+id/btn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

Java脈動檢測

Button clickButton = (Button) findViewById(R.id.btn1);
if (clickButton != null) {
    clickButton.setOnClickListener( new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            /***Do what you want with the click here***/
        }
    });
}

為了簡化asp問題2所述,您可以使用這樣的lambda方法來節省變量內存並避免在視圖類中上下導航

//method 1
findViewById(R.id.buttonSend).setOnClickListener(v -> {
          // handle click
});

但是如果您希望在方法中一次將點擊事件應用於您的按鈕。

您可以使用@D 的問題 3。 陳回答。 但不要忘記使用View.OnClickListener實現您的視圖類。

其他正確使用問題#3

我推薦你這個視頻 它清楚地指導了按鈕單擊的處理。

問題#1 - 這些是處理視圖點擊的唯一方法。

問題2 -
選項#1/選項#4 - 選項#1 和選項#4 之間沒有太大區別。 我看到的唯一區別是在一種情況下活動是實現 OnClickListener,而在另一種情況下,會有一個匿名實現。

選項#2 - 在此方法中將生成一個匿名類。 這種方法有點麻煩,因為如果您有多個按鈕,則需要多次執行此操作。 對於匿名類,您必須小心處理內存泄漏。

選項#3 - 不過,這是一個簡單的方法。 通常,程序員在編寫任何方法之前盡量不使用它,因此這種方法並沒有被廣泛使用。 你會看到大多數人使用選項#4。 因為它在代碼方面更干凈。

第 1 步:創建一個 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">

    <Button
        android:id="@+id/btnClickEvent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Click Me" />
</LinearLayout>

第 2 步:創建 MainActivity:

package com.scancode.acutesoft.telephonymanagerapp;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity implements View.OnClickListener {

    Button btnClickEvent;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnClickEvent = (Button) findViewById(R.id.btnClickEvent);
        btnClickEvent.setOnClickListener(MainActivity.this);

    }

    @Override
    public void onClick(View v) {
        //Your Logic
    }
}

快樂編碼!

還有各種庫形式的可用選項,可以使使用其他 MVVM 框架的人非常熟悉此過程。

https://developer.android.com/topic/libraries/data-binding/

顯示官方庫的示例,它允許您像這樣綁定按鈕:

<Button
    android:text="Start second activity"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:onClick="@{() -> presenter.showList()}"
/>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM