[英]Android: how to handle button click
在非 Java 和非 Android 領域擁有豐富的經驗,我正在學習 Android。
我對不同的領域有很多困惑,其中之一是如何處理按鈕點擊。 至少有 4 種方法 (!!!),它們在此處簡要列出
為了保持一致性,我將列出它們:
在活動中擁有View.OnClickListener
類的成員,並將其分配給將在onCreate
活動方法中處理onClick
邏輯的實例。
在“onCreate”活動方法中創建“onClickListener”並使用 setOnClickListener 將其分配給按鈕
在活動本身中實現“onClickListener”並將“this”指定為按鈕的偵聽器。 如果 Activity 的按鈕很少,則應分析按鈕 ID 以針對正確的按鈕執行“onClick”處理程序
在實現“onClick”邏輯的活動上擁有公共方法並將其分配給活動 xml 聲明中的按鈕
問題 1:
這些都是方法,還有其他選擇嗎? (我不需要任何其他的,只是好奇)
對我來說,最直觀的方法是最新的:它需要輸入的代碼最少,而且可讀性最強(至少對我而言)。
不過,我沒有看到這種方法被廣泛使用。 使用它有什么缺點?
問題2:
每種方法的優缺點是什么? 請分享您的經驗或好的鏈接。
歡迎任何反饋!
PS 我已經嘗試使用谷歌搜索並找到有關此主題的內容,但我發現的唯一內容是描述“如何”做到這一點,而不是為什么它是好是壞。
問題1:不幸的是,您說最直觀的那個在Android中使用最少。 據我了解,您應該將 UI (XML) 和計算功能(Java 類文件)分開。 它還使調試更容易。 以這種方式閱讀和思考 Android imo 實際上要容易得多。
問題2:我認為主要使用的兩個是#2和#3。 我將使用 Button clickButton 作為示例。
是匿名類的形式。
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 會變得很長。 所以這就是他喜歡使用的原因:
假設您有 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當布局上有未生成的按鈕(但顯然是靜態的)時,我經常使用最后一個。
如果您在實踐中和業務應用程序中使用它,請特別注意這里,因為當您使用像 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.