Autore Topic: [facile] Creare nel proprio layout una tastiera personalizzata con KeyboardView  (Letto 18689 volte)

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Livello di difficoltà: facile
Target SDK: 8
Min SDK: 1
Link al sorgente: https://github.com/rciovati/Android-KeyboardView-Example

Talvolta nella propria applicazione si ha la necessità di mostrare una tastiera che ha solo un insieme particolare di caratteri.
Poichè la tastiera di default di Android non permette grossi margini di personalizzazione riguardo ai tasti da mostrare, se non impostando gli attributi android:inputType e android:inputMethod, per le esigenze più particolari una possibile soluzione è offerta dal metodo presentato in questo tutorial.
Questo metodo non è particolarmente "pubblicizzato" ma è possibile vedere una live-demo su qualsiasi terminale Android, portandosi nelle impostazioni di sicurezza e successivamente nella schermata per impostare una password di sblocco per il telefono.

Tramite questo tutorial vedremo quindi come è possibile, con l'ausilio della classe Keyboard e della classe KeyboardView creare una tastiera dal layout, definito tramite xml, del tutto arbitrario. Nel nostro caso si tratta di una tastiera con i numeri da 0 a 9, il tasto per cancellare e il tasto enter.



Il primo step consiste nel creare il layout xml della tastiera:

Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
        android:keyWidth="33%p" android:horizontalGap="0px"
        android:verticalGap="0px" android:keyHeight="54dip">

        <Row>
                <Key android:codes="8" android:keyLabel="1" android:keyEdgeFlags="left" />
                <Key android:codes="9" android:keyLabel="2" />
                <Key android:codes="10" android:keyLabel="3" android:keyEdgeFlags="right" />
        </Row>

        <Row>
                <Key android:codes="11" android:keyLabel="4" android:keyEdgeFlags="left" />
                <Key android:codes="12" android:keyLabel="5" />
                <Key android:codes="13" android:keyLabel="6" android:keyEdgeFlags="right" />
        </Row>

        <Row>
                <Key android:codes="14" android:keyLabel="7" android:keyEdgeFlags="left" />
                <Key android:codes="15" android:keyLabel="8" />
                <Key android:codes="16" android:keyLabel="9" android:keyEdgeFlags="right" />
        </Row>

        <Row>
                <Key android:codes="67" android:keyIcon="@drawable/sym_keyboard_delete"
                        android:iconPreview="@drawable/sym_keyboard_delete"
                        android:keyEdgeFlags="left" />
                <Key android:codes="7" android:keyLabel="0" />
                <Key android:codes="66" android:keyEdgeFlags="right"
                        android:keyIcon="@drawable/sym_keyboard_feedback_return"
                        android:iconPreview="@drawable/sym_keyboard_feedback_return" />
        </Row>

</Keyboard>

Come potete notare dal codice, si procede prima di tutto con la definizione dei tasti che ciascuna riga deve avere.
Per ciascun tasto si definisce poi il codice (i codici dei tasti li potete trovare nella classe KeyEvent | Android Developers ) e il testo o l'icona da mostrare sopra di esso. Per la definizione completa degli attributi che è possibile impostare vi rimando alla documentazione:

Keyboard: Keyboard | Android Developers
Row: Keyboard.Row | Android Developers
Key Keyboard.Key | Android Developers

Il secondo step invece consiste nell'inserire nel layout dell'Activity dentro la quale vogliamo mostrare la nostra tastiera personalizzata un oggetto di tipo KeyboardView. Nel mio esempio ho provveduto ad estendere questa classe per aggiungergli un metodo per cambiargli la visibilità tramite un'animazione, vi riporto quindi sia il codice Java che quello XML del layout.

Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<!-- In questo layout è stato utilizzato un contenitore RelativeLayout per
        fare in modo che la nostra tastiera rimanga ancorata nella parte inferiore
        della schermata, proprio come la tastiera originale di android -->
<RelativeLayout android:id="@+id/LinearLayout1"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="fill_parent"
        android:layout_height="fill_parent">

        <LinearLayout android:layout_width="fill_parent"
                android:id="@+id/container" android:layout_alignParentTop="true"
                android:layout_height="fill_parent" android:layout_above="@+id/keyboard_view">
                <EditText android:layout_width="fill_parent" android:id="@+id/target"
                        android:layout_height="wrap_content" />
        </LinearLayout>

        <it.anddev.tutorial.CustomKeyboardView
                android:id="@+id/keyboard_view" android:visibility="gone"
                android:layout_width="fill_parent" android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"></it.anddev.tutorial.CustomKeyboardView>

</RelativeLayout>

Codice (Java): [Seleziona]
public class CustomKeyboardView extends KeyboardView {

        public CustomKeyboardView(Context context, AttributeSet attrs) {
                super(context, attrs);
        }

        public void showWithAnimation(Animation animation) {
                animation.setAnimationListener(new AnimationListener() {

                        @Override
                        public void onAnimationStart(Animation animation) {
                                // TODO Auto-generated method stub

                        }

                        @Override
                        public void onAnimationRepeat(Animation animation) {
                                // TODO Auto-generated method stub

                        }

                        @Override
                        public void onAnimationEnd(Animation animation) {
                                setVisibility(View.VISIBLE);
                        }
                });
               
                setAnimation(animation);
        }
}

Come potete vedere la classe Java aggiunge solo un metodo riguardante l'animazione. Se non siete interessati a questo aspetto potete evitare di creare una custom-view e utilizzare direttamente un oggetto di tipo android.inputmethod.KeyboardView nel layout xml.

La documentazione della classe KeyboardView è disponibile a questo indirizzo:

KeyboardView | Android Developers

Il terzo step riguarda invece la creazione di un listener per gestire la pressione di un tasto nella nostra tastiera personalizzata. Questo listener si dichiara implementando l'interfaccia OnKeyboardActionListener

Codice (Java): [Seleziona]
public class BasicOnKeyboardActionListener implements OnKeyboardActionListener {

        private Activity mTargetActivity;

        public BasicOnKeyboardActionListener(Activity targetActivity) {
                mTargetActivity = targetActivity;
        }
       
        //Altri metodo rimossi
       
        @Override
        public void onKey(int primaryCode, int[] keyCodes) {
                long eventTime = System.currentTimeMillis();
                KeyEvent event = new KeyEvent(eventTime, eventTime,
                                KeyEvent.ACTION_DOWN, primaryCode, 0, 0, 0, 0,
                                KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE);

                mTargetActivity.dispatchKeyEvent(event);
        }
}

Il listener così implementato fa in modo che la pressione di un tasto venga propagata all'activity in cui è ospitata la nostra KeyboardView, proprio come se venisse premuto un tasto nella tastiera Android. Questa interfaccia permette inoltre di intercettare eventi quali lo swipe sulla tastiera, la pressione e il rilascio di un tasto e altri. In questo tutorial, per brevità, non sono stati gestiti.

Il quarto e ultimo step "mette tutto insieme", vi posto quindi il codice, molto semplice, dell'activity:

Codice (Java): [Seleziona]
public class KeyboardWidgetTutorialActivity extends Activity {

        private CustomKeyboardView mKeyboardView;
        private View mTargetView;
        private Keyboard mKeyboard;

        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);

                setContentView(R.layout.main);
                mKeyboard = new Keyboard(this, R.xml.keyboard);
                mTargetView = (EditText) findViewById(R.id.target);
                mTargetView.setOnTouchListener(new View.OnTouchListener() {

                        @Override
                        public boolean onTouch(View v, MotionEvent event) {
                                // Dobbiamo intercettare l'evento onTouch in modo da aprire la
                                // nostra tastiera e prevenire che venga aperta quella di
                                // Android
                                showKeyboardWithAnimation();
                                return true;
                        }
                });

                mKeyboardView = (CustomKeyboardView) findViewById(R.id.keyboard_view);
                mKeyboardView.setKeyboard(mKeyboard);
                mKeyboardView
                                .setOnKeyboardActionListener(new BasicOnKeyboardActionListener(
                                                this));
        }

        /***
         * Mostra la tastiera a schermo con una animazione di slide dal basso
         */

        private void showKeyboardWithAnimation() {
                if (mKeyboardView.getVisibility() == View.GONE) {
                        Animation animation = AnimationUtils
                                        .loadAnimation(KeyboardWidgetTutorialActivity.this,
                                                        R.anim.slide_in_bottom);
                        mKeyboardView.showWithAnimation(animation);
                }
        }
}

Note:

E' possibile personalizzare il background dei tasti con l'attributo android:keyBackground impostabile tramite xml sulla KeyboardView. Tuttavia non è possibile specificare il background a livello del singolo tasto quindi i tasti avranno tutti lo stesso background.


Sorgenti:

Scaricabili tramite git

Codice: [Seleziona]
git clone git://github.com/rciovati/Android-KeyboardView-Example.git
« Ultima modifica: 04 Dicembre 2011, 11:43:31 CET da JD »

Offline gsources75

  • Utente normale
  • ***
  • Post: 327
  • Respect: +9
    • Google+
    • pepigno75
    • devandroid_it
    • Mostra profilo
  • Dispositivo Android:
    Samsung Galaxy Nexus S - Vodafone Smart -BB Bold- Iphone 4-
  • Play Store ID:
    Giuseppe+Sorce
  • Sistema operativo:
    Ubuntu-Windows Seven- Mac Lion
Re:Creare nel proprio layout una tastiera personalizzata tramite KeyboardView
« Risposta #1 il: 04 Agosto 2011, 17:26:29 CEST »
0
Complimenti. Bel tutorial...

Una domanda ok per il background unico ma che tipo di personalizzazioni si potrebbero fare ?

Il font  e lo style del desto ?

La domanda stupida è quella che non si fa

Offline Mikykly91

  • Utente junior
  • **
  • Post: 91
  • Respect: 0
    • Google+
    • Mostra profilo
  • Dispositivo Android:
    Htc one, Nexus 7 2013
  • Play Store ID:
    Michele Marconi
  • Sistema operativo:
    Surface 2 pro win 8.1
Re:Creare nel proprio layout una tastiera personalizzata tramite KeyboardView
« Risposta #2 il: 20 Settembre 2011, 15:43:47 CEST »
0
Ho provato a cambiare gli android:code con caratteri unicode del tipo "\u00c4" ma niente alla pressione del tasto non scrive nulla nell'edittext!!!
Qualcuno sa perchè??

grazie

Offline droide

  • Nuovo arrivato
  • *
  • Post: 25
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    HTC DESIRE Z
Re:Creare nel proprio layout una tastiera personalizzata tramite KeyboardView
« Risposta #3 il: 28 Settembre 2011, 01:37:32 CEST »
0
Salve ragazzi. Era proprio quello che cercavo  :-[. Mi chiedevo se era possibile ottenere una cosa simile all'immagine. Con l'unica differenza che al posto dei bottoni di sotto, si potrebbe tranquillamente sostituire con OK e un CANCEL.

Piu che altro il problema è trovare la lista dei country code con la bandierina. Infine mi chiedevo se esiste qualche pattern per controllare se il numero di telefono inserito sia valido. Quello che voglio creare è un activity carina che mi permette di inserire il numero di cellulare e memorizzarlo nelle sharedpreferences. Grazie in anticipo.

 

Offline Ricky`

  • Amministratore
  • Utente storico
  • *****
  • Post: 3489
  • Respect: +506
    • Github
    • Google+
    • rciovati
    • Mostra profilo
Re:Creare nel proprio layout una tastiera personalizzata tramite KeyboardView
« Risposta #4 il: 28 Settembre 2011, 10:49:13 CEST »
0
Infine mi chiedevo se esiste qualche pattern per controllare se il numero di telefono inserito sia valido.

prova a dare un occhio a questa classe, ha un po' di metodi per maneggiare i numeri di telefono :)
PhoneNumberUtils | Android Developers


Offline droide

  • Nuovo arrivato
  • *
  • Post: 25
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    HTC DESIRE Z
Re:Creare nel proprio layout una tastiera personalizzata tramite KeyboardView
« Risposta #5 il: 12 Ottobre 2011, 01:52:25 CEST »
0
E' possibile fare in modo che la tastiera ritorna in GONE(Completamente nascosto) alla pressione di un tasto aggiuntivo? Avete in mente il bottone con l'immaginetta delle tastiera e la freccia in giù presente nella tastiera(phone dialer)  che compare quando dobbiamo effettuare una chiamata?

Vorrei realizzare una tastiera simile.

Il tasto verde in basso al centro con scritto conferma che mi salva il numero di cell con sharedPreference.
Sulla sinistra il pulsante che nasconde la tastiera e sulla destra il tastino |<-- per cancellare la EditText.

Praticamente se la tastiera viene nascosta, basta semplicemente cliccare nuovamente sulla editText per farla riapparire. 

Grazie  :-).

« Ultima modifica: 12 Ottobre 2011, 01:55:25 CEST da droide »

Offline kalacta269

  • Utente normale
  • ***
  • Post: 152
  • Respect: +14
    • Mostra profilo
  • Dispositivo Android:
    Asus Transformer pad tf300
  • Sistema operativo:
    windows7
Re:[facile] Creare nel proprio layout una tastiera personalizzata con KeyboardView
« Risposta #6 il: 19 Dicembre 2011, 16:06:39 CET »
0
ciao seguendo il tuo tutorial incappo in un errore nel file xml principale......
ovvero quando aggiungo il pezzetto di codice che si riferisce al customKeybord mi si blocca tutto.... devo metterlo in un una particolare zona del codice xml?? ti posto pure il mio codice.....

Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/AbsoluteLayout1"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:background="@drawable/gradiente_scuro" >
   
       
<!--    per fare in modo che il table layout non sovrasti tutto lo schermo bisogna impostare il valore dell'heigth a mano  
-->

       

    <LinearLayout
       android:id="@+id/linearLayout1"
       android:layout_width="650dp"
       android:layout_height="165dp"
       android:layout_x="10dp"
       android:layout_y="106dp" >
       

         <ScrollView
       android:id="@+id/ScrollView01"
       android:layout_width="wrap_content"
       android:layout_height="400dp" >

        <TableLayout
           android:id="@+id/TableLayout01"
           android:layout_width="fill_parent"
           android:layout_height="wrap_content"
            android:stretchColumns="0" >                   
        </TableLayout>
 
    </ScrollView>
   
    </LinearLayout>
   
    <EditText
       android:id="@+id/ricercaArticoliEditText"
       android:layout_width="279dp"
       android:layout_height="wrap_content"
       android:layout_x="9dp"
       android:layout_y="27dp"
       android:imeOptions="actionSearch|flagNoExtractUi" >

        <requestFocus />
    </EditText>

    <Button
       android:id="@+id/confermaArticoliButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_x="532dp"
       android:layout_y="297dp"
       android:text="Inserisci prodotti" />

    <Button
       android:id="@+id/indietroArticoliButton"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_x="14dp"
       android:layout_y="297dp"
       android:text="Indietro" />

    <TextView
       android:id="@+id/textView1"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_x="50dp"
       android:layout_y="7dp"
       android:text="Inserisci il prodotto da cercare"
       android:textAppearance="?android:attr/textAppearanceSmall"
       android:textColor="#FFFF99" />

    <TextView
       android:id="@+id/textView17"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_x="413dp"
       android:layout_y="89dp"
       android:text="PRZ"
       android:textAppearance="?android:attr/textAppearanceSmall"
       android:textColor="#FFFF99" />

    <TextView
       android:id="@+id/TextView01"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_x="502dp"
       android:layout_y="89dp"
       android:text="P"
       android:textAppearance="?android:attr/textAppearanceSmall"
       android:textColor="#FFFF99" />

    <TextView
       android:id="@+id/TextView02"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_x="548dp"
       android:layout_y="89dp"
       android:text="CL"
       android:textAppearance="?android:attr/textAppearanceSmall"
       android:textColor="#FFFF99" />

    <TextView
       android:id="@+id/TextView03"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_x="584dp"
       android:layout_y="89dp"
       android:text="QTA"
       android:textAppearance="?android:attr/textAppearanceSmall"
       android:textColor="#FFFF99" />

    <TextView
       android:id="@+id/textView13"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_x="108dp"
       android:layout_y="89dp"
       android:text="Descrizione"
       android:textAppearance="?android:attr/textAppearanceSmall"
       android:textColor="#FFFF99" />

    <TextView
       android:id="@+id/TextView04"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_x="14dp"
       android:layout_y="89dp"
       android:text="Cod.art."
       android:textAppearance="?android:attr/textAppearanceSmall"
       android:textColor="#FFFF99" />

   <it.anddev.tutorial.CustomKeyboardView
       android:id="@+id/keyboard_view"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:layout_alignParentBottom="true"
       android:visibility="gone" >
    </it.anddev.tutorial.CustomKeyboardView>
</AbsoluteLayout>

Offline AngelMagli

  • Nuovo arrivato
  • *
  • Post: 18
  • Respect: 0
    • Mostra profilo
Re:[facile] Creare nel proprio layout una tastiera personalizzata con KeyboardView
« Risposta #7 il: 05 Ottobre 2013, 17:09:01 CEST »
0
Salve, vorrei sapere come posso impostare la tastiera che ho creato come predefinita, in modo tale da poterla utilizzare ovunque.
Spero di esser stato chiaro =)

Distinti Saluti

Offline Alet

  • Nuovo arrivato
  • *
  • Post: 19
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Acer Iconia Tab A501
  • Sistema operativo:
    Windows 7,Windows Xp
Re:[facile] Creare nel proprio layout una tastiera personalizzata con KeyboardView
« Risposta #8 il: 18 Novembre 2013, 16:44:04 CET »
0
Scusate se riesumo questo tutorial ma mi sto scervellando con un problema piuttosto banale.
Io ho seguito il tutorial alla lettera e la tastiera sembra fuzionarmi correttamente, l'unico inconveniente che riscontro è che quando (per un motivo qualsiasi) apro una Custom DialogBox la tastiera mi rimane "sotto" alla dialog impedendomi cosi la pressione dei tasti.
Come si può risolvere la cosa?
Di seguito metto qualche riga di codice:

 private void showKeyboardWithAnimation() {
       try{
         if (mKeyboardView.getVisibility() == View.GONE) {
            Animation animation = AnimationUtils.loadAnimation(OrdiniArticoli.this,R.anim.slide_in_bottom);
            mKeyboardView.showWithAnimation(animation);
         }
       }catch(Exception e){
          System.err.println(e);
       }
      }


Dove OrdiniArticoli è la classe principale che implementa la Custom DialogBox.
Sul Layout xml invece ho specificato

  <form.CustomKeyboardView
                android:id="@+id/keyboard_view" android:visibility="visible"
                android:layout_width="fill_parent" android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:alpha="70"></form.CustomKeyboardView>

sia nell'xml della classe principale( OrdiniArticoli) sia nell xml della DialogBox


spero che qualcuno può aiutarmi perchè sto "impanicatissimo" XD
GRAZIEEEEEEEE

Offline pivio666

  • Nuovo arrivato
  • *
  • Post: 1
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    LG Optimus 4X
  • Sistema operativo:
    Windows 7
Anche a me interesserebbe questa cosa  ;-)

Salve, vorrei sapere come posso impostare la tastiera che ho creato come predefinita, in modo tale da poterla utilizzare ovunque.
Spero di esser stato chiaro =)

Distinti Saluti

Offline edoardotognoni

  • Nuovo arrivato
  • *
  • Post: 1
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Sistema operativo:
    Mac OSX
Re:[facile] Creare nel proprio layout una tastiera personalizzata con KeyboardView
« Risposta #10 il: 17 Settembre 2014, 12:06:42 CEST »
0
Non è vero che non è possibile settare vari background per i singoli tasti della tastiera. Si crea una custom KeyboardView, so overrida il metodo onDraw e si fa un if sui codici dei tasti e si setta il background. Per maggiori info:
How to set different background of keys for Android Custom Keyboard - Stack Overflow

Offline waterfall10

  • Nuovo arrivato
  • *
  • Post: 7
  • Respect: 0
    • Mostra profilo
  • Sistema operativo:
    Mac OS X
Re:[facile] Creare nel proprio layout una tastiera personalizzata con KeyboardView
« Risposta #11 il: 22 Febbraio 2016, 10:57:58 CET »
0
è possibile spostare il layout? far si che non si sposti in mezzo alla pagina?
« Ultima modifica: 22 Febbraio 2016, 13:13:53 CET da waterfall10 »