Autore Topic: View e setOnKeyListener non funzionante  (Letto 1563 volte)

Offline Paciotti

  • Utente junior
  • **
  • Post: 51
  • Respect: 0
    • sergiofabbrini
    • paciotti83
    • paciotti
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S
  • Play Store ID:
    Paciotti
  • Sistema operativo:
    Mac OS X 10.6 & Ubuntu 10.10
View e setOnKeyListener non funzionante
« il: 11 Marzo 2011, 17:50:13 CET »
0
Ho realizzato un semplice contatore che ora vorrei controllare con i pulsanti del volume.
Analizzando l'interfaccia View.OnKeyListener sono arrivato a scrivere questo codice
Codice (Java): [Seleziona]
keyPressed.setOnKeyListener(new OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                        switch (keyCode) {
                                case KeyEvent.KEYCODE_VOLUME_UP:
                                        keyPressed.setText("Volume UP");
                                        break;
                                case KeyEvent.KEYCODE_VOLUME_DOWN:
                                        keyPressed.setText("Volume DOWN");
                                        break;
                                default:
                                        break;
                        }
                }
                return true;
        }
});
dove keyPressed è una TextView dove momentaneamente vorrei visualizzare il pulsante premuto.
Ho provato anche a cambiare keyPressed con timer, l'EditText che normalmente ha il focus (c'è sempre il cursore lampeggiante e la casella è evidenziata, questo credo voglia dire avere il focus...), ma il risultato non cambia: la pressione dei tasti comporta il cambiamento del volume.
Altra prova è stata quella di cambiare il tasto volume con il tasto Home, ma niente da fare.
Mi viene il dubbio che stia sbagliando qualche concetto fondamentale (d'altra parte è un progetto per imparare).
Sto lavorando su SDK 2.1, ma la classe e le interfacce utilizzate sono presenti fin dalle API 1 (provato sia su emulatore 2.1 che cellulare 2.2)
Qualche consiglio?

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
« Ultima modifica: 11 Marzo 2011, 20:01:50 CET da Ricky` »

Offline Paciotti

  • Utente junior
  • **
  • Post: 51
  • Respect: 0
    • sergiofabbrini
    • paciotti83
    • paciotti
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S
  • Play Store ID:
    Paciotti
  • Sistema operativo:
    Mac OS X 10.6 & Ubuntu 10.10
Re:View e setOnKeyListener non funzionante
« Risposta #2 il: 11 Marzo 2011, 20:09:33 CET »
0

Suppongo che dovrebbe essere qualcosa del genere:

Codice (Java): [Seleziona]
public class Prova extends Activity implements OnKeyListener{
       
        private Button control, reset;
        private TextView timer, keyPressed;
        private EditText max;
        private RadioGroup direction;
       
        private int maxValue;
        private Timer countdown;
       
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) { ... }

        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) { ... }
}

Questo è il codice di onCreate:

Codice (Java): [Seleziona]
@Override
public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        control = (Button) findViewById(R.id.control);
        reset = (Button) findViewById(R.id.reset);
        timer = (TextView) findViewById(R.id.timer);
        max = (EditText) findViewById(R.id.max);
        direction = (RadioGroup) findViewById(R.id.direction);
        keyPressed = (TextView) findViewById(R.id.keyPressed);
       
        maxValue = Integer.decode(max.getText().toString());
        countdown = new Timer(maxValue); // Crea il timer
       
        control.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View view) {
                        RadioButton selected = (RadioButton) findViewById(direction.getCheckedRadioButtonId());
                        // Oggetto RadioButton per poter leggere la direzione
                        if (timer.getText() == getResources().getString(R.string.timerTitle)) {
                                // Se siamo all'inizio
                                timer.setText(Integer.toString(countdown.getCurrent())); // Scrive
                        } else {
                                timer.setText(Integer.toString(countdown.newValue(selected)));
                                // Altrimenti richiama un nuovo valore.
                        }
                }
        });
        reset.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View view) {
                        countdown.reset(Integer.decode(max.getText().toString()));
                        // Chiama reset() passando il nuovo max
                        timer.setText(Integer.toString(countdown.getCurrent()));
                        // Reimposta il valore sull'output
                }
        });
}

mentre questo è quello di onKey():

Codice (Java): [Seleziona]
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
                switch (keyCode) {
                case KeyEvent.KEYCODE_VOLUME_UP:
                        keyPressed.setText("Volume UP");
                        break;
                case KeyEvent.KEYCODE_VOLUME_DOWN:
                        keyPressed.setText("Volume DOWN");
                        break;
                default:
                        break;
                }
        }
        return true;
}

Stessa cosa: premendo i pulsanti del volume... cambia solo il volume!
« Ultima modifica: 11 Marzo 2011, 20:21:10 CET da Paciotti »

Offline Paciotti

  • Utente junior
  • **
  • Post: 51
  • Respect: 0
    • sergiofabbrini
    • paciotti83
    • paciotti
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S
  • Play Store ID:
    Paciotti
  • Sistema operativo:
    Mac OS X 10.6 & Ubuntu 10.10
Re:View e setOnKeyListener non funzionante
« Risposta #3 il: 11 Marzo 2011, 20:23:42 CET »
0
... poi non sono riuscito a capire a cosa faccia riferimento quella "View v" all'interno di onKey() ...
Come dovrei usarla, ammesso che mi sia utile?
« Ultima modifica: 11 Marzo 2011, 20:53:08 CET da Paciotti »

Offline teskio

  • Moderatore globale
  • Utente normale
  • *****
  • Post: 387
  • Respect: +118
    • Github
    • Google+
    • Mostra profilo
    • Skullab
  • Dispositivo Android:
    Cubot GT99 / SurfTab Ventos 10.1
  • Play Store ID:
    Skullab Software
  • Sistema operativo:
    windows 7 / ubuntu 12.04
Re:View e setOnKeyListener non funzionante
« Risposta #4 il: 11 Marzo 2011, 21:02:25 CET »
0
Citazione da: Paciotti
... poi non sono riuscito a capire a cosa faccia riferimento quella "View v" all'interno di onKey() ...

E' il riferimento alla View che ha generato l'evento.

Comunque prova ad usare : public boolean  onKeyDown  (int keyCode, KeyEvent  event)
Facendo l'override del metodo direttamente nell'Activity :

Codice (Java): [Seleziona]
public class MiaActivity extends Activity {
    @Override
     protected boolean onKeyDown(int keyCode, KeyEvent event) {
         switch (keyCode) {
                case KeyEvent.KEYCODE_VOLUME_UP:
                        keyPressed.setText("Volume UP");
                        break;
                case KeyEvent.KEYCODE_VOLUME_DOWN:
                        keyPressed.setText("Volume DOWN");
                        break;
                default:
                        break;
                }
        return true ;
     }

Offline Paciotti

  • Utente junior
  • **
  • Post: 51
  • Respect: 0
    • sergiofabbrini
    • paciotti83
    • paciotti
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S
  • Play Store ID:
    Paciotti
  • Sistema operativo:
    Mac OS X 10.6 & Ubuntu 10.10
Re:View e setOnKeyListener non funzionante
« Risposta #5 il: 11 Marzo 2011, 21:12:46 CET »
0
E' il riferimento alla View che ha generato l'evento.

Quale evento? L'evento "Key"? Cosa c'entra la View con un tasto fisico premuto?

Ora provo in questo terzo modo, ma mi piacerebbe capire che differenza c'è tra i tre e soprattutto perchè i primi due non funzionano...

Offline Paciotti

  • Utente junior
  • **
  • Post: 51
  • Respect: 0
    • sergiofabbrini
    • paciotti83
    • paciotti
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S
  • Play Store ID:
    Paciotti
  • Sistema operativo:
    Mac OS X 10.6 & Ubuntu 10.10
Re:View e setOnKeyListener non funzionante
« Risposta #6 il: 11 Marzo 2011, 21:35:38 CET »
0
Con il terzo metodo funziona!
Ora rimane solo da capire come funzionino gli altri...  o_O

Offline Paciotti

  • Utente junior
  • **
  • Post: 51
  • Respect: 0
    • sergiofabbrini
    • paciotti83
    • paciotti
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S
  • Play Store ID:
    Paciotti
  • Sistema operativo:
    Mac OS X 10.6 & Ubuntu 10.10
Re:View e setOnKeyListener non funzionante
« Risposta #7 il: 15 Marzo 2011, 16:39:28 CET »
0
Nessuno che sa spiegare la differenza concettuale tra i tre metodi e prova ad avanzare un'ipotesi sul perchè ne funzioni solo uno?

Offline teskio

  • Moderatore globale
  • Utente normale
  • *****
  • Post: 387
  • Respect: +118
    • Github
    • Google+
    • Mostra profilo
    • Skullab
  • Dispositivo Android:
    Cubot GT99 / SurfTab Ventos 10.1
  • Play Store ID:
    Skullab Software
  • Sistema operativo:
    windows 7 / ubuntu 12.04
Re:View e setOnKeyListener non funzionante
« Risposta #8 il: 16 Marzo 2011, 01:06:48 CET »
+5
Allora...vediamo se riesco a spiegare e a spiegarmi  :-P

1° Metodo
View.setOnKeyListener

Il primo metodo che hai usato concettualmente è corretto. L'interfaccia OnKeyListener o meglio il metodo onKey in essa, viene invocato quando viene generato un evento "key" inviato alla view alla quale è associata l'interfaccia stessa.  :-X Cosa vuol dire ? In pratica significa che quando viene premuto un tasto, il quale però era indirizzato alla view, viene generato l'evento, e quindi viene eseguito il metodo onKey. E qui c'è il primo problema. Nell'esempio che hai riportato, l'interfaccia era associata ad una TextView. Il problema è che la pressione dei tasti in questo caso non viene indirizzata alla TextView, ergo l'evento non verrà mai generato. Se invece di una TextView venisse associata ad una EditText, l'evento verrebbe generato a patto che si stia inviando "l'informazione" (chiamiamola così) alla EditText in questione, cioè in pratica ci si stia scrivendo dentro (o che comunque l'input dell'utente sia focalizzato su quella EditText).
Puoi provare a mettere nel tuo layout due EditText e associare OnKeyListener ad una di essa. Vedrai come si comporta il listener se viene dato il "focus" ad una EditText piuttosto che all'altra. ;-)
Ora viene da chiedersi come mai non funzioni l'implementazione dell'OnKeyListener sull'Activity :-o

2° Metodo
Activity implements OnKeyListener ?

Una Activity non è una View ma un contenitore di View. Sorge un problema, chi ha il focus ?
Verrebbe da rispondere che l'Activity stessa ha il focus in quanto contenitore, ma non è così. E' un po' come la TextView del primo esempio, c'è, è visibile, ma non ha focalizzata su di se l'attenzione necessaria :-P
Per questo L'Activity implementa nativamente un'altra interfaccia e cioè : android.view.KeyEvent.Callback
Anche le View implementano questa interfaccia, possiamo testarlo in Eclipse digitando il punto dopo una variabile oggetto TextView e notare che tra i metodi c'è ad esempio onKeyDown
Tutto questo ci riporta quindi al terzo metodo

3° Metodo
L'ovveride di KeyEvent.Callback

Utilizzando quindi l'interfaccia KeyEvent.Callback, già implementata dall'Activity, ci basterà fare l'override dei 4 metodi dell'interfaccia :
onKeyDown
onKeyLongPress
onKeyMultiple
onKeyUp


Cosa che potremmo fare ad esempio se volessimo creare una custom View, cioè un componente personalizzato, andando poi a fare l'override dei 4 metodi sopra citati :-)

Spero di essere stato chiaro e capibile o almeno un po' utile. :-P

Offline Paciotti

  • Utente junior
  • **
  • Post: 51
  • Respect: 0
    • sergiofabbrini
    • paciotti83
    • paciotti
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy S
  • Play Store ID:
    Paciotti
  • Sistema operativo:
    Mac OS X 10.6 & Ubuntu 10.10
Re:View e setOnKeyListener non funzionante
« Risposta #9 il: 16 Marzo 2011, 01:23:27 CET »
0
Direi che difficilmente potevi essere più chiaro di così!
Grazie mille!