2013-02-08 200 views
67

在非Java和非Android領域有豐富的經驗,我正在學習Android。Android:如何處理按鈕點擊

我對不同領域有很多困惑,其中之一是如何處理按鈕點擊。有這樣做(!),他們簡要列出here

一致性目的的至少4路,我會一一列舉:

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

  2. 創建「onClickListener」和活動使用setOnClickListener

  3. 實施「onClickListener」本身它分配給該按鈕並指定「本」爲按鈕的監聽器。對於活動只有少量按鈕的情況,應分析按鈕ID以執行適當按鈕的「onClick」處理程序

  4. 對實現'onClick'邏輯的活動具有公共方法並將其分配給活動中的按鈕XML聲明

問題1:

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

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

雖然,我沒有看到這種方法廣泛使用。使用它有什麼好處?

問題2:

有什麼利弊/每個這些方法的利弊?請分享您的經驗或一個很好的鏈接。

歡迎任何反饋!

P.S.我試圖找到谷歌併爲這個話題找到一些東西,但我發現的唯一事情是描述「如何」這樣做,而不是爲什麼它是好的或壞的。

回答

108

問題1: 不幸的是,你說的最直觀的是Android中最少使用的。據我所知,你應該分開你的UI(XML)和計算功能(Java Class Files)。它也使得調試更容易。實際上,閱讀這種方式比較容易,並考慮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*** 
      } 
     }); 

這是我最喜歡的,因爲它的onClick方法就在button變量設置在findViewById的旁邊。看起來非常整潔,所有處理這個clickButton按鈕視圖的東西都在這裏。

我的同事評論的一個騙局是想象你有很多需要onclick監聽器的觀點。你可以看到你的onCreate會變得很長。這樣,爲什麼他喜歡用:

說你有,5個clickButtons:

確保您的活動/片段實現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. 和可能位於由OnClick方法中使用的onCreate任何其他對象將不得不做成一個字段。

讓我知道如果您想了解更多信息。我沒有完全回答你的問題,因爲這是一個相當長的問題。如果我找到一些網站,我會擴大我的答案,現在我只是給一些經驗。

+1

對於選項2,你會希望把它:clickButton.setOnClickListener(新View.OnClickListener(){@覆蓋公共無效的onClick(視圖v) {// TODO你想做什麼}});以幫助解決OnClickListener – ColossalChris 2015-03-25 13:54:10

+0

選項3可能是使用MVP模式最簡單和最容易擴展的選項。 – Raffaeu 2016-01-26 12:05:43

+0

選項2仍然可以生成'onCreate()',這不是很長。點擊監聽器分配和匿名類可以分解爲一個單獨的輔助方法,該方法從'onCreate()'調用。 – 2016-02-29 07:28:12

0

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

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

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

選項#3 - 雖然這是一個簡單的方法。通常,程序員在編寫它們之前不要使用任何方法,因此這種方法沒有被廣泛使用。你會發現大多數人使用選項#4。因爲它在代碼方面更乾淨。

+0

嗨拉夫,感謝您的回答。但是,請您澄清一下您的意思:對於匿名類,您必須小心處理內存泄漏。內存泄漏如何來到這裏? – Budda 2013-02-09 01:26:20

+0

你一定要知道:如果你創建你的應用程序不能將創建一個類的幾個實例,但幾類,包括它們的實例的生命週期過程中可能會多次調用方法內部的匿名類。您可以通過使用常規的內部類並將實例化偵聽器作爲實例字段來避免這種情況。嘗試通過構造函數參數讓偵聽器狀態感知來減少不同的偵聽器類。常規的內部類爲您提供自定義構造函數和其他方法的好處。 – Risadinha 2013-10-15 09:26:35

9

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

如果您在實踐中和業務應用程序中使用它,請特別注意這一點,因爲當您像ProGuard一樣使用source obfuscater時,您需要在活動中標記這些方法以免被混淆。

要使用此方法歸檔某種編譯時安全性,請查看Android Lintexample)。


#2利弊所有方法幾乎相同和教訓應該是:

使用什麼都最合適的還是感覺最直觀的給你。

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

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

我傾向於不執行活動中的OnClickListener,這會有點混亂,不時(尤其是當你實現多個其他事件沒有人知道什麼this都在做)。

+0

我下面一樣,但仍然沒有得到任何輸出功能,我的代碼和查詢是在這裏:http://stackoverflow.com/questions/25107427/can-we-make-2-different-functions-in-same-jni -in-Android的NDK-使用-C/25187447 noredirect = 1#comment39221983_25187447 – Rocket 2014-08-07 19:42:57

1

選項1和2涉及使用內部類,將使代碼種類雜亂。 選項2有點亂,因爲每個按鈕都會有一個監聽器。如果你有少量的按鈕,這沒關係。 對於選項4,我認爲這將更難以調試,因爲您將不得不返回第四個xml和java代碼。 當我必須處理多個按鈕點擊時,我個人使用選項3。

4

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

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)方法。然後,你可以assing將此活動作爲偵聽器按鈕,因爲它已經實現了接口,並覆蓋的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); 
    } 

} 

(IMHO)4個方法中使用時,多個按鈕具有相同的處理程序,並可以申報一個方法並將此方法分配給xml佈局中的多個按鈕,也可以爲一個按鈕創建一個方法,但在這種情況下,我傾向於使用 來在活動類中聲明處理程序。

5

我更喜歡選項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更難。

+0

我要胡扯一點,並提出第五種選擇(不,不是主演布魯斯·威利斯:)),選項2的變體:使用演示類模型 - 視圖 - 演示框架來處理點擊。它使自動化測試更容易。查看此鏈接以獲取更好的信息:https://codelabs.developers.google.com/codelabs/android-testing/index.html – 2017-06-29 13:50:58

0

步驟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 
    } 
} 

HappyCoding

1

我的樣品,在Android Studio中測試2.1

在XML佈局定義按鈕

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

Java的脈動檢測

​​