2013-02-08 11 views
67

Avendo una solida esperienza in area non Java e non Android, sto imparando Android.Android: come gestire il clic del pulsante

Ho molta confusione con aree diverse, una delle quali è come gestire i clic sui pulsanti. Ci sono almeno 4 modo di fare che (!!!), sono elencate brevemente here

fini di coerenza io li elenco:

  1. a un membro della classe View.OnClickListener nell'attività e assegnarlo a un'istanza che gestirà la logica onClick nel metodo di attività onCreate.

  2. Crea 'onClickListener' nel metodo dell'attività 'onCreate' e assegnare al pulsante utilizzando setOnClickListener

  3. Implementare 'onClickListener' in attività stessa e assegnare 'questo' come listener per il pulsante. Nel caso in cui l'attività abbia pochi pulsanti, l'id del pulsante deve essere analizzato per eseguire il gestore onClick per il pulsante corretto

  4. Avere un metodo pubblico sull'attività che implementa la logica 'onClick' e assegnarlo al pulsante nell'attività dichiarazione XML

domanda # 1:

sono quelli tutti i metodi, c'è qualche altra opzione? (Non ho bisogno di altri, solo curioso)

Per me, il modo più intuitivo sarebbe l'ultimo: richiede la minima quantità di codice da digitare ed è il più leggibile (almeno per me) .

Tuttavia, non vedo questo approccio ampiamente utilizzato. Quali sono i contro per usarlo?

Domanda # 2:

Quali sono i pro/contro per ciascuno di questi metodi? Condividi la tua esperienza o un buon link.

Qualsiasi commento è benvenuto!

P.S. Ho provato a cercare qualcosa su Google per questo argomento, ma le uniche cose che ho trovato sono la descrizione "come" per farlo, non perché è buono o cattivo.

risposta

108

Domanda 1: Sfortunatamente quella in cui dici che è più intuitiva è la meno utilizzata in Android.Come ho capito, dovresti separare la tua UI (XML) e la funzionalità computazionale (Java Class Files). Inoltre facilita il debugging. In realtà è molto più facile leggere in questo modo e pensare ad Android imo.

Domanda 2: Credo che i due principalmente utilizzati sono # 2 e # 3. Userò un pulsante clickButton come esempio.

è sotto forma di una classe anonima.

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*** 
      } 
     }); 

Questo è il mio preferito in quanto ha il metodo onClick proprio accanto a dove la variabile pulsante è stato impostato con il findViewById. Sembra molto pulito e ordinato che tutto ciò che riguarda questa vista pulsante ClickButton si trovi qui.

Una truffa che il mio collega commenta, è che immaginate di avere molte viste che richiedono l'ascoltatore onclick. Puoi vedere che il tuo onCreate durerà molto a lungo. In modo che il motivo per cui egli ama usare:

Dire che hai, 5 clickButtons:

Assicuratevi che la vostra attività/Frammento implementare 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 
    } 
} 

In questo modo, come il mio collega spiega è più nitido nei suoi occhi, poiché tutto il calcolo onClick è gestito in un unico posto e non affolla il metodo onCreate. Ma il lato negativo che vedo è che il:

  1. stessi punti di vista,
  2. e qualsiasi altro oggetto che potrebbe essere situato nel onCreate utilizzato dal metodo onClick dovrà essere trasformato in un campo.

Fatemi sapere se desiderate ulteriori informazioni. Non ho risposto alla tua domanda completamente perché è una domanda piuttosto lunga. E se trovo alcuni siti, espanderò la mia risposta, in questo momento sto solo facendo esperienza.

+1

Per l'opzione 2 ti consigliamo di farlo: clickButton.setOnClickListener (new View.OnClickListener() {@Override public void onClick (Visualizza v) {// TODO cosa vuoi fare}}); per aiutarlo a risolvere OnClickListener – ColossalChris

+0

L'opzione 3 è probabilmente la più pulita e semplice da estendere con il pattern MVP. – Raffaeu

+0

L'opzione 2 può ancora produrre 'onCreate()' che non è terribilmente lungo. Gli assegnamenti del listener di clic e le classi anonime possono essere scomposti in un metodo di helper separato chiamato da 'onCreate()'. –

0

Domanda n. 1: questi sono l'unico modo per gestire i clic di vista.

Domanda n. 2 -
Opzione n. 1/Opzione n. 4 - Non c'è molta differenza tra l'opzione n. 1 e l'opzione n. L'unica differenza che vedo è che in un caso l'attività sta implementando OnClickListener, mentre, nell'altro caso, ci sarebbe un'implementazione anonima.

Opzione n. 2: in questo metodo verrà generata una classe anonima. Questo metodo è un po 'fastidioso, dato che avresti bisogno di farlo più volte, se hai più pulsanti. Per le classi anonime, devi stare attento a gestire le perdite di memoria.

Opzione # 3 - Anche se, questo è un modo semplice.Di solito, i programmatori cercano di non utilizzare alcun metodo finché non lo scrivono, e quindi questo metodo non è ampiamente utilizzato. Vedresti che la maggior parte delle persone usa l'Opzione 4. Perché è più pulito in termini di codice.

+0

Hi Gaurav, grazie per la risposta. Ma puoi chiarire cosa intendi qui: per le classi anonime, devi stare attento a gestire le perdite di memoria. Come vengono le perdite di memoria qui? – Budda

+0

Devi solo essere consapevole che: se crei una classe anonima all'interno di un metodo che potrebbe essere richiamato più volte durante la vita della tua app, non verranno create diverse istanze di una classe, ma diverse classi, incluse le istanze. Puoi evitarlo usando classi interne regolari e istanziando gli ascoltatori come campi di istanze. Cerca di ridurre le diverse classi di ascoltatori rendendo consapevole lo stato del listener tramite gli argomenti del costruttore. Una normale classe interna ti dà il vantaggio di costruttori personalizzati e altri metodi. – Risadinha

9

# 1 Uso spesso l'ultimo quando si hanno pulsanti sul layout che non sono generati (ma statici ovviamente).

Se lo si utilizza in pratica e in un'applicazione aziendale, prestare particolare attenzione qui, perché quando si utilizza source obfuscater come ProGuard, è necessario contrassegnare questi metodi nella propria attività in modo da non essere offuscati.

Per archiviare una sorta di protezione in fase di compilazione con questo approccio, dare un'occhiata a Android Lint (example).


# 2 Pro e contro per tutti metodi sono quasi la stessa e la lezione dovrebbe essere:

Usa che cosa mai è più appropriato o si sente più intuitiva per voi.

Se si deve assegnare lo stesso OnClickListener a più istanze di pulsanti, salvarlo nella classe-scope (# 1). Se avete bisogno di un semplice ascoltatore per un pulsante, rendono un'implementazione anonimo:

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

tendo a non attuare la OnClickListener nell'attività, questo diventa un po 'di confusione di tanto in tanto (soprattutto quando si implementa più altro evento -handlers e nessuno sa cosa sta facendo this).

+0

Sto seguendo lo stesso, ma non ottengo ancora output per la funzione, il mio codice e la query è qui: http://stackoverflow.com/questions/25107427/can-we-make-2-different-functions-in-same-jni -in-android-ndk-using-c/25187447? noredirect = 1 # comment39221983_25187447 – Rocket

1

Le opzioni 1 e 2 prevedono l'utilizzo di una classe interna che renderà il tipo di ammasso di codice. L'opzione 2 è un po 'caotica perché ci sarà un ascoltatore per ogni pulsante. Se hai un piccolo numero di pulsanti, va bene. Per l'opzione 4, penso che sarà più difficile eseguire il debug in quanto sarà necessario tornare indietro e il quarto il codice xml e java. Personalmente utilizzo l'opzione 3 quando devo gestire più clic sui pulsanti.

4

modo più utilizzato è, dichiarazione anonima

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

Inoltre è possibile creare l'oggetto View.OnClickListener e impostarlo su tasto più tardi, ma è comunque necessario eseguire l'override metodo onClick per esempio

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

Quando l'attività implementa l'interfaccia di OnClickListener, è necessario sovrascrivere il metodo onClick (Visualizza v) a livello di attività. Poi si può assing questa attività come ascoltatore a pulsante, perché implementa già dell'interfaccia e ridefinisce il metodo() 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) approccio 4-esimo utilizzato quando più pulsanti hanno stesso gestore, e si può dichiarare un metodo nella classe di attività e assegnare questo metodo a più pulsanti nel layout xml, inoltre è possibile creare un metodo per un pulsante, ma in questo caso preferisco per dichiarare i gestori all'interno della classe di attività.

5

Preferisco l'opzione 4, ma mi sembra intuitivo perché lavoro troppo con Grails, Groovy e JavaFX. Le connessioni "magiche" tra la vista e il controller sono comuni in tutto. E 'importante dare un nome al metodo ben:

Nella vista, aggiungere il metodo onClick al pulsante o altro widget:

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

Poi nella classe, gestire il metodo:

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

Ancora, dai un nome al metodo in modo chiaro, qualcosa che dovresti fare comunque, e la manutenzione diventa di seconda natura.

Un grande vantaggio è che ora è possibile scrivere unit test per il metodo. L'opzione 1 può farlo, ma 2 e 3 sono più difficili.

+0

Vado un po 'a chiacchierare e suggerisco una quinta opzione (no, non con protagonista Bruce Willis :)), una variante delle opzioni 2: utilizzare una classe Presenter in un framework Model-View-Presenter da gestire scatti. Rende il test automatico MOLTO più semplice. Dai un'occhiata a questo link per maggiori informazioni: https://codelabs.developers.google.com/codelabs/android-testing/index.html –

0

Fase 1: Creata un file 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> 

Passo 2: Creare 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

mio campione, provato in studio Android 2.1

pulsante Definisci nel layout xml

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

Java pulsazione rilevare

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***/ 
     } 
    }); 
}