Voglio creare una tastiera personalizzata. Non so come farlo usando XML e Java. L'immagine seguente è un modello della tastiera che voglio realizzare. Ha bisogno solo di numeri.
Voglio creare una tastiera personalizzata. Non so come farlo usando XML e Java. L'immagine seguente è un modello della tastiera che voglio realizzare. Ha bisogno solo di numeri.
Risposte:
Prima di tutto avrai bisogno di un keyboard.xml
file che verrà inserito nella res/xml
cartella (se la cartella non esiste, creala).
<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="15%p"
android:keyHeight="15%p" >
<Row>
<Key android:codes="1" android:keyLabel="1" android:horizontalGap="4%p"/>
<Key android:codes="2" android:keyLabel="2" android:horizontalGap="4%p"/>
<Key android:codes="3" android:keyLabel="3" android:horizontalGap="4%p" />
<Key android:codes="4" android:keyLabel="4" android:horizontalGap="4%p" />
<Key android:codes="5" android:keyLabel="5" android:horizontalGap="4%p" />
</Row>
<Row>
<Key android:codes="6" android:keyLabel="6" android:horizontalGap="4%p"/>
<Key android:codes="7" android:keyLabel="7" android:horizontalGap="4%p"/>
<Key android:codes="8" android:keyLabel="8" android:horizontalGap="4%p" />
<Key android:codes="9" android:keyLabel="9" android:horizontalGap="4%p" />
<Key android:codes="0" android:keyLabel="0" android:horizontalGap="4%p" />
</Row>
<Row>
<Key android:codes="-1" android:keyIcon="@drawable/backspace" android:keyWidth="34%p" android:horizontalGap="4%p"/>
<Key android:codes="100" android:keyLabel="Enter" android:keyWidth="53%p" android:horizontalGap="4%p"/>
</Row>
</Keyboard>
** Nota che dovrai creare il backspace
drawable e posizionarlo nella cartella res / drawable-ldpi con una dimensione molto piccola (come 18x18 pixel)
Quindi nel file xml che vuoi che venga utilizzato (dove si trova il tuo TextView) dovresti aggiungere il seguente codice:
<RelativeLayout
...
>
.....
<android.inputmethodservice.KeyboardView
android:id="@+id/keyboardview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:visibility="gone"
/>
......
</RelativeLayout>
** Nota che il file xml in cui inserirai android.inputmethodservice.KeyboardView
, deve essere RelativeLayout
per poter impostare il alignParentBottom="true"
(Di solito le tastiere sono presentate nella parte inferiore dello schermo)
Quindi è necessario aggiungere il seguente codice nella onCreate
funzione del Activity
che gestisce il a cui TextView
si desidera collegare la tastiera
// Create the Keyboard
mKeyboard= new Keyboard(this,R.xml.keyboard);
// Lookup the KeyboardView
mKeyboardView= (KeyboardView)findViewById(R.id.keyboardview);
// Attach the keyboard to the view
mKeyboardView.setKeyboard( mKeyboard );
// Do not show the preview balloons
//mKeyboardView.setPreviewEnabled(false);
// Install the key handler
mKeyboardView.setOnKeyboardActionListener(mOnKeyboardActionListener);
** Nota che mKeyboard
e mKeyboardView
sono variabili di classe privata che devi creare.
Quindi è necessaria la seguente funzione per aprire la tastiera (è necessario associarla al TextView tramite la onClick
proprietà xml)
public void openKeyboard(View v)
{
mKeyboardView.setVisibility(View.VISIBLE);
mKeyboardView.setEnabled(true);
if( v!=null)((InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0);
}
E finalmente hai bisogno del OnKeyboardActionListener
che gestirà i tuoi eventi
private OnKeyboardActionListener mOnKeyboardActionListener = new OnKeyboardActionListener() {
@Override public void onKey(int primaryCode, int[] keyCodes)
{
//Here check the primaryCode to see which key is pressed
//based on the android:codes property
if(primaryCode==1)
{
Log.i("Key","You just pressed 1 button");
}
}
@Override public void onPress(int arg0) {
}
@Override public void onRelease(int primaryCode) {
}
@Override public void onText(CharSequence text) {
}
@Override public void swipeDown() {
}
@Override public void swipeLeft() {
}
@Override public void swipeRight() {
}
@Override public void swipeUp() {
}
};
Spero che aiuti!!!
La maggior parte del codice si trova qui
Questa risposta spiega come creare una tastiera di sistema personalizzata che può essere utilizzata in qualsiasi app che un utente ha installato sul proprio telefono. Se vuoi creare una tastiera che verrà utilizzata solo all'interno della tua app, guarda la mia altra risposta .
L'esempio seguente sarà simile a questo. Puoi modificarlo per qualsiasi layout di tastiera.
I passaggi seguenti mostrano come creare una tastiera di sistema personalizzata funzionante. Per quanto possibile ho provato a rimuovere qualsiasi codice non necessario. Se ci sono altre funzionalità di cui hai bisogno, ho fornito collegamenti a ulteriore aiuto alla fine.
Ho chiamato il mio progetto "Tastiera personalizzata". Chiamalo come vuoi. Non c'è nient'altro di speciale qui. Lascerò solo il MainActivity
e "Hello World!" layout così com'è.
Aggiungi i seguenti due file alla res/layout
cartella della tua app :
keyboard_view.xml
Questa vista è come un contenitore che terrà la nostra tastiera. In questo esempio c'è una sola tastiera, ma puoi aggiungere altre tastiere e scambiarle dentro e fuori da questa KeyboardView
.
<?xml version="1.0" encoding="utf-8"?>
<android.inputmethodservice.KeyboardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/keyboard_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:keyPreviewLayout="@layout/key_preview"
android:layout_alignParentBottom="true">
</android.inputmethodservice.KeyboardView>
key_preview.xml
L'anteprima dei tasti è un layout che viene visualizzato quando si preme un tasto della tastiera. Mostra solo quale tasto stai premendo (nel caso in cui le tue dita grandi e grasse lo coprano). Questo non è un popup a scelta multipla. Per questo dovresti controllare la vista Candidati .
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="@android:color/white"
android:textColor="@android:color/black"
android:textSize="30sp">
</TextView>
Crea una xml
cartella nella tua res
cartella. (Fare clic con il pulsante destro del mouse res
e scegliere Nuovo> Directory .)
Quindi aggiungi i seguenti due file xml. (Fare clic con il pulsante destro del mouse sulla xml
cartella e scegliere Nuovo> File di risorse XML .)
number_pad.xml
È qui che inizia a diventare più interessante. Questo Keyboard
definisce il layout dei tasti .
<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="20%p"
android:horizontalGap="5dp"
android:verticalGap="5dp"
android:keyHeight="60dp">
<Row>
<Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"/>
<Key android:codes="50" android:keyLabel="2"/>
<Key android:codes="51" android:keyLabel="3"/>
<Key android:codes="52" android:keyLabel="4"/>
<Key android:codes="53" android:keyLabel="5" android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:codes="54" android:keyLabel="6" android:keyEdgeFlags="left"/>
<Key android:codes="55" android:keyLabel="7"/>
<Key android:codes="56" android:keyLabel="8"/>
<Key android:codes="57" android:keyLabel="9"/>
<Key android:codes="48" android:keyLabel="0" android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:codes="-5"
android:keyLabel="DELETE"
android:keyWidth="40%p"
android:keyEdgeFlags="left"
android:isRepeatable="true"/>
<Key android:codes="10"
android:keyLabel="ENTER"
android:keyWidth="60%p"
android:keyEdgeFlags="right"/>
</Row>
</Keyboard>
Ecco alcune cose da notare:
keyWidth
: Questa è la larghezza predefinita di ogni chiave. I 20%p
mezzi che ogni chiave dovrebbe occupare il 20% della larghezza del p Arent. Può essere sovrascritto da singoli tasti, tuttavia, come puoi vedere è successo con i tasti Elimina e Invio nella terza riga.keyHeight
: È hard coded qui, ma potresti usare qualcosa di simile @dimen/key_height
per impostarlo dinamicamente per diverse dimensioni dello schermo.Gap
: La distanza orizzontale e verticale indica quanto spazio lasciare tra i tasti. Anche se lo imposti, 0px
c'è ancora un piccolo spazio vuoto.codes
: Può essere un valore Unicode o un codice personalizzato che determina cosa accade o cosa viene immesso quando viene premuto il tasto. Verifica keyOutputText
se vuoi inserire una stringa Unicode più lunga.keyLabel
: Questo è il testo visualizzato sulla chiave.keyEdgeFlags
: Indica a quale bordo deve essere allineata la chiave.isRepeatable
: Se tieni premuto il tasto, continuerà a ripetere l'input.method.xml
Questo file indica al sistema i sottotipi del metodo di input disponibili. Sto solo includendo una versione minima qui.
<?xml version="1.0" encoding="utf-8"?>
<input-method
xmlns:android="http://schemas.android.com/apk/res/android">
<subtype
android:imeSubtypeMode="keyboard"/>
</input-method>
Crea un nuovo file Java. Chiamiamolo MyInputMethodService
. Questo file lega tutto insieme. Gestisce l'input ricevuto dalla tastiera e lo invia a qualsiasi vista lo stia ricevendo (una EditText
, ad esempio).
public class MyInputMethodService extends InputMethodService implements KeyboardView.OnKeyboardActionListener {
@Override
public View onCreateInputView() {
// get the KeyboardView and add our Keyboard layout to it
KeyboardView keyboardView = (KeyboardView) getLayoutInflater().inflate(R.layout.keyboard_view, null);
Keyboard keyboard = new Keyboard(this, R.xml.number_pad);
keyboardView.setKeyboard(keyboard);
keyboardView.setOnKeyboardActionListener(this);
return keyboardView;
}
@Override
public void onKey(int primaryCode, int[] keyCodes) {
InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
switch (primaryCode) {
case Keyboard.KEYCODE_DELETE:
CharSequence selectedText = ic.getSelectedText(0);
if (TextUtils.isEmpty(selectedText)) {
// no selection, so delete previous character
ic.deleteSurroundingText(1, 0);
} else {
// delete the selection
ic.commitText("", 1);
}
break;
default:
char code = (char) primaryCode;
ic.commitText(String.valueOf(code), 1);
}
}
@Override
public void onPress(int primaryCode) { }
@Override
public void onRelease(int primaryCode) { }
@Override
public void onText(CharSequence text) { }
@Override
public void swipeLeft() { }
@Override
public void swipeRight() { }
@Override
public void swipeDown() { }
@Override
public void swipeUp() { }
}
Appunti:
OnKeyboardActionListener
ascolti per l'input dalla tastiera. Richiede anche tutti quei metodi vuoti in questo esempio.InputConnection
è quello che viene utilizzato per inviare input per un'altra vista come un EditText
.Metto quest'ultimo anziché il primo perché si riferisce ai file che abbiamo già aggiunto sopra. Per registrare la tua tastiera personalizzata come tastiera di sistema, devi aggiungere una service
sezione al tuo file AndroidManifest.xml . Mettilo nella application
sezione dopo activity
.
<manifest ...>
<application ... >
<activity ... >
...
</activity>
<service
android:name=".MyInputMethodService"
android:label="Keyboard Display Name"
android:permission="android.permission.BIND_INPUT_METHOD">
<intent-filter>
<action android:name="android.view.InputMethod"/>
</intent-filter>
<meta-data
android:name="android.view.im"
android:resource="@xml/method"/>
</service>
</application>
</manifest>
Questo è tutto! Ora dovresti essere in grado di eseguire la tua app. Tuttavia, non vedrai molto finché non abiliti la tastiera nelle impostazioni.
Ogni utente che desidera utilizzare la tastiera dovrà abilitarlo nelle impostazioni di Android. Per istruzioni dettagliate su come eseguire questa operazione, vedere il seguente collegamento:
Ecco un riepilogo:
Ora dovresti essere in grado di utilizzare la tastiera ovunque tu possa digitare su Android.
La tastiera sopra è utilizzabile, ma per creare una tastiera che altre persone vorranno usare probabilmente dovrai aggiungere più funzionalità. Studia i link sottostanti per scoprire come.
Non ti piace come KeyboardView
appare e si comporta lo standard ? Io certamente no. Sembra che non sia stato aggiornato da Android 2.0. Che ne dici di tutte quelle tastiere personalizzate nel Play Store? Non assomigliano per niente alla brutta tastiera sopra.
La buona notizia è che puoi personalizzare completamente l'aspetto e il comportamento della tua tastiera. Dovrai fare le seguenti cose:
ViewGroup
. Potresti riempirlo con Button
s o persino creare le tue visualizzazioni chiave personalizzate per quella sottoclasse View
. Se utilizzi le visualizzazioni popup, prendi nota di questo .onKeyClicked(String text)
o onBackspace()
.keyboard_view.xml
, key_preview.xml
o number_pad.xml
descritto nelle direzioni sopra dal momento che questi sono tutti per lo standard KeyboardView
. Gestirai tutti questi aspetti dell'interfaccia utente nella tua visualizzazione personalizzata.MyInputMethodService
classe, implementa il listener di tastiera personalizzato che hai definito nella tua classe di tastiera. Questo è al posto di KeyboardView.OnKeyboardActionListener
, che non è più necessario.MyInputMethodService
della tua classe onCreateInputView()
, crea e restituisci un'istanza della tua tastiera personalizzata. Non dimenticare di impostare l'ascoltatore personalizzato della tastiera su this
.Questa risposta spiega come creare una tastiera personalizzata da utilizzare esclusivamente all'interno della tua app. Se vuoi creare una tastiera di sistema che può essere utilizzata in qualsiasi app, guarda la mia altra risposta .
L'esempio sarà simile a questo. Puoi modificarlo per qualsiasi layout di tastiera.
Ho chiamato il mio progetto InAppKeyboard
. Chiama il tuo come vuoi.
Layout della tastiera
Aggiungi un file di layout alla res/layout
cartella. Ho chiamato il mio keyboard
. La tastiera sarà una visualizzazione composta personalizzata che gonferemo da questo file di layout xml. Puoi usare il layout che preferisci per disporre i tasti, ma io sto usando un file LinearLayout
. Nota i merge
tag.
res / layout / keyboard.xml
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/button_1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="1"/>
<Button
android:id="@+id/button_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="2"/>
<Button
android:id="@+id/button_3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="3"/>
<Button
android:id="@+id/button_4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="4"/>
<Button
android:id="@+id/button_5"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="5"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/button_6"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="6"/>
<Button
android:id="@+id/button_7"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="7"/>
<Button
android:id="@+id/button_8"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="8"/>
<Button
android:id="@+id/button_9"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="9"/>
<Button
android:id="@+id/button_0"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="0"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/button_delete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="Delete"/>
<Button
android:id="@+id/button_enter"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:text="Enter"/>
</LinearLayout>
</LinearLayout>
</merge>
Layout attività
A scopo dimostrativo la nostra attività ha un unico EditText
e la tastiera è in basso. Ho chiamato la mia visualizzazione tastiera personalizzata MyKeyboard
. (Aggiungeremo presto questo codice, quindi per ora ignoriamo l'errore.) Il vantaggio di mettere tutto il codice della nostra tastiera in un'unica vista è che ne semplifica il riutilizzo in un'altra attività o app.
res / layout / activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.inappkeyboard.MainActivity">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#c9c9f1"
android:layout_margin="50dp"
android:padding="5dp"
android:layout_alignParentTop="true"/>
<com.example.inappkeyboard.MyKeyboard
android:id="@+id/keyboard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentBottom="true"/>
</RelativeLayout>
Aggiungi un nuovo file Java. Ho chiamato il mio MyKeyboard
.
La cosa più importante da notare qui è che non esiste alcun collegamento fisico a qualsiasi EditText
o Activity
. Ciò semplifica il collegamento a qualsiasi app o attività che ne abbia bisogno. Questa visualizzazione della tastiera personalizzata utilizza anche un InputConnection
, che imita il modo in cui una tastiera di sistema comunica con un file EditText
. Questo è il modo in cui evitiamo gli hard link.
MyKeyboard
è una vista composta che gonfia il layout della vista che abbiamo definito sopra.
MyKeyboard.java
public class MyKeyboard extends LinearLayout implements View.OnClickListener {
// constructors
public MyKeyboard(Context context) {
this(context, null, 0);
}
public MyKeyboard(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyKeyboard(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
// keyboard keys (buttons)
private Button mButton1;
private Button mButton2;
private Button mButton3;
private Button mButton4;
private Button mButton5;
private Button mButton6;
private Button mButton7;
private Button mButton8;
private Button mButton9;
private Button mButton0;
private Button mButtonDelete;
private Button mButtonEnter;
// This will map the button resource id to the String value that we want to
// input when that button is clicked.
SparseArray<String> keyValues = new SparseArray<>();
// Our communication link to the EditText
InputConnection inputConnection;
private void init(Context context, AttributeSet attrs) {
// initialize buttons
LayoutInflater.from(context).inflate(R.layout.keyboard, this, true);
mButton1 = (Button) findViewById(R.id.button_1);
mButton2 = (Button) findViewById(R.id.button_2);
mButton3 = (Button) findViewById(R.id.button_3);
mButton4 = (Button) findViewById(R.id.button_4);
mButton5 = (Button) findViewById(R.id.button_5);
mButton6 = (Button) findViewById(R.id.button_6);
mButton7 = (Button) findViewById(R.id.button_7);
mButton8 = (Button) findViewById(R.id.button_8);
mButton9 = (Button) findViewById(R.id.button_9);
mButton0 = (Button) findViewById(R.id.button_0);
mButtonDelete = (Button) findViewById(R.id.button_delete);
mButtonEnter = (Button) findViewById(R.id.button_enter);
// set button click listeners
mButton1.setOnClickListener(this);
mButton2.setOnClickListener(this);
mButton3.setOnClickListener(this);
mButton4.setOnClickListener(this);
mButton5.setOnClickListener(this);
mButton6.setOnClickListener(this);
mButton7.setOnClickListener(this);
mButton8.setOnClickListener(this);
mButton9.setOnClickListener(this);
mButton0.setOnClickListener(this);
mButtonDelete.setOnClickListener(this);
mButtonEnter.setOnClickListener(this);
// map buttons IDs to input strings
keyValues.put(R.id.button_1, "1");
keyValues.put(R.id.button_2, "2");
keyValues.put(R.id.button_3, "3");
keyValues.put(R.id.button_4, "4");
keyValues.put(R.id.button_5, "5");
keyValues.put(R.id.button_6, "6");
keyValues.put(R.id.button_7, "7");
keyValues.put(R.id.button_8, "8");
keyValues.put(R.id.button_9, "9");
keyValues.put(R.id.button_0, "0");
keyValues.put(R.id.button_enter, "\n");
}
@Override
public void onClick(View v) {
// do nothing if the InputConnection has not been set yet
if (inputConnection == null) return;
// Delete text or input key value
// All communication goes through the InputConnection
if (v.getId() == R.id.button_delete) {
CharSequence selectedText = inputConnection.getSelectedText(0);
if (TextUtils.isEmpty(selectedText)) {
// no selection, so delete previous character
inputConnection.deleteSurroundingText(1, 0);
} else {
// delete the selection
inputConnection.commitText("", 1);
}
} else {
String value = keyValues.get(v.getId());
inputConnection.commitText(value, 1);
}
}
// The activity (or some parent or controller) must give us
// a reference to the current EditText's InputConnection
public void setInputConnection(InputConnection ic) {
this.inputConnection = ic;
}
}
Per le tastiere di sistema, Android usa un InputMethodManager per puntare la tastiera sul focus EditText
. In questo esempio, l'attività prenderà il suo posto fornendo il collegamento dalla EditText
alla nostra tastiera personalizzata a.
Dato che non stiamo usando la tastiera di sistema, dobbiamo disabilitarla per evitare che venga visualizzato quando tocchiamo il EditText
. Secondo, dobbiamo prendere il InputConnection
dal EditText
e darlo alla nostra tastiera.
MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText editText = (EditText) findViewById(R.id.editText);
MyKeyboard keyboard = (MyKeyboard) findViewById(R.id.keyboard);
// prevent system keyboard from appearing when EditText is tapped
editText.setRawInputType(InputType.TYPE_CLASS_TEXT);
editText.setTextIsSelectable(true);
// pass the InputConnection from the EditText to the keyboard
InputConnection ic = editText.onCreateInputConnection(new EditorInfo());
keyboard.setInputConnection(ic);
}
}
Se la tua attività ha più EditText, dovrai scrivere il codice per passare l'EditText corretto InputConnection
alla tastiera. (Puoi farlo aggiungendo un OnFocusChangeListener
e OnClickListener
al EditTexts. Vedi questo articolo per una discussione di questo.) Potresti anche voler nascondere o mostrare la tua tastiera nei momenti appropriati.
Questo è tutto. Dovresti essere in grado di eseguire l'app di esempio ora e inserire o eliminare il testo come desiderato. Il prossimo passo è modificare tutto per adattarlo alle proprie esigenze. Ad esempio, in alcune delle mie tastiere ho utilizzato TextView invece dei pulsanti perché è più facile personalizzarli.
TextView
piuttosto a Button
se vuoi migliorare l'aspetto delle chiavi. Quindi rendi lo sfondo un disegnabile che cambia lo stato dell'aspetto quando viene premuto.View
e tastiere personalizzate che sottoclasse ViewGroup
. La tastiera dispone tutti i tasti a livello di programmazione. I tasti utilizzano un'interfaccia per comunicare con la tastiera (simile a come i frammenti comunicano con un'attività). Questo non è necessario se hai bisogno di un solo layout di tastiera poiché il layout xml funziona bene per quello. Ma se vuoi vedere un esempio di ciò su cui ho lavorato, dai un'occhiata a tutte le classi Key*
e qui . Nota che utilizzo anche una vista contenitore la cui funzione è di scambiare le tastiere dentro e fuori.Keyboard*
InputMethodManager#showInputMethodPicker()
. Se la tastiera originale non dispone di tale tasto, tuttavia, l'unico modo in cui gli utenti possono passare alla tastiera è farlo manualmente nelle impostazioni di sistema. Apple è superiore ad Android in quest'area, perché Apple richiede che tutte le tastiere abbiano un tasto per cambiare tastiera.
EditText
, sarà necessario aggiungerne uno onFocusChangedListener
in modo che quando ricevono il focus puoi assegnare il InputConnection
dalla corrente EditText
alla tua tastiera personalizzata.
Usa KeyboardView
:
KeyboardView kbd = new KeyboardView(context);
kbd.setKeyboard(new Keyboard(this, R.xml.custom));
kbd.setOnKeyboardActionListener(new OnKeyboardActionListener() {
....
}
ora hai kbd
una visualizzazione normale.
La cosa bella di questo è che R.xml.custom
fa riferimento a /res/xml/custom.xml
, che definisce in xml il layout della tastiera. Per ulteriori informazioni su questo file, guarda qui: Keyboard , Keyboard.Row , Keyboard.Key .
Ecco un progetto di esempio per una tastiera morbida.
https://developer.android.com/guide/topics/text/creating-input-method.html
I tuoi dovrebbero essere nelle stesse linee con un layout diverso.
Modifica: se hai bisogno della tastiera solo nella tua applicazione, è molto semplice! Crea un layout lineare con orientamento verticale e crea 3 layout lineari al suo interno con orientamento orizzontale. Quindi posizionare i pulsanti di ciascuna riga in ciascuno di questi layout lineari orizzontali e assegnare la proprietà del peso ai pulsanti. Usa android: layout_weight = 1 per tutti, in modo che siano equidistanti.
Questo risolverà. Se non hai ottenuto ciò che ti aspettavi, inserisci il codice qui e noi siamo qui per aiutarti!
Uno dei migliori esempi ben documentati che ho trovato.
http://www.fampennings.nl/maarten/android/09keyboard/index.htm
KeyboardView
vengono forniti il file XML e il codice sorgente correlati.
Mi sono imbattuto in questo post di recente quando stavo cercando di decidere quale metodo utilizzare per creare la mia tastiera personalizzata. Ho trovato l'API del sistema Android molto limitata, quindi ho deciso di creare la mia tastiera in-app. Utilizzando la risposta di Suragch come base per la mia ricerca, ho continuato a progettare il mio componente di tastiera . È pubblicato su GitHub con una licenza MIT. Si spera che questo farà risparmiare a qualcun altro molto tempo e mal di testa.
L'architettura è piuttosto flessibile. C'è una vista principale (CustomKeyboardView) che puoi inserire con qualsiasi layout di tastiera e controller desideri.
Devi solo dichiarare CustomKeyboardView nella tua attività xml (puoi farlo anche a livello di programmazione):
<com.donbrody.customkeyboard.components.keyboard.CustomKeyboardView
android:id="@+id/customKeyboardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
Quindi registra il tuo EditText con esso e digli quale tipo di tastiera dovrebbero usare:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val numberField: EditText = findViewById(R.id.testNumberField)
val numberDecimalField: EditText = findViewById(R.id.testNumberDecimalField)
val qwertyField: EditText = findViewById(R.id.testQwertyField)
keyboard = findViewById(R.id.customKeyboardView)
keyboard.registerEditText(CustomKeyboardView.KeyboardType.NUMBER, numberField)
keyboard.registerEditText(CustomKeyboardView.KeyboardType.NUMBER_DECIMAL, numberDecimalField)
keyboard.registerEditText(CustomKeyboardView.KeyboardType.QWERTY, qwertyField)
}
CustomKeyboardView gestisce il resto!
Ho la palla che rotola con una tastiera Number, NumberDecimal e QWERTY. Sentiti libero di scaricarlo e creare i tuoi layout e controller. Assomiglia a questo:
Anche se questa non è l'architettura con cui decidi di utilizzare, si spera che sia utile vedere il codice sorgente per una tastiera in-app funzionante.
Di nuovo, ecco il collegamento al progetto: Tastiera in-app personalizzata
Bene, Suragch ha dato la risposta migliore finora, ma ha saltato alcune cose minori che erano importanti per compilare l'app.
Spero di dare una risposta migliore di Suragch migliorando la sua risposta. Aggiungerò tutti gli elementi mancanti che non ha inserito.
Ho compilato il mio apk utilizzando l'app Android, APK Builder 1.1.0. Quindi iniziamo.
Per costruire un'app Android abbiamo bisogno di un paio di file e cartelle organizzati in un certo formato e capitalizzati di conseguenza.
res layout -> file xml che raffigurano l'aspetto dell'app sul telefono. Simile a come html modella l'aspetto della pagina web sul browser. Consentire alla tua app di adattarsi agli schermi di conseguenza.
valori -> dati costanti come colors.xml, strings.xml, styles.xml. Questi file devono essere scritti correttamente.
drawable -> pics {jpeg, png, ...}; Dai loro un nome qualsiasi.
mipmap -> altre foto. utilizzato per l'icona dell'app?
xml -> più file xml.
src -> agisce come JavaScript in html. i file di layout avvieranno la visualizzazione iniziale e il file java controllerà dinamicamente gli elementi dei tag e attiverà gli eventi. Gli eventi possono anche essere attivati direttamente nel layout.xml proprio come in html.
AndroidManifest.xml -> Questo file registra di cosa tratta la tua app. Nome dell'applicazione, tipo di programma, autorizzazioni necessarie, ecc. Questo sembra rendere Android piuttosto sicuro. I programmi letteralmente non possono fare ciò che non chiedevano nel Manifest.
Ora ci sono 4 tipi di programmi Android, un'attività, un servizio, un fornitore di contenuti e un ricevitore di trasmissione. La nostra tastiera sarà un servizio che gli consentirà di funzionare in background. Non apparirà nell'elenco delle app da avviare; ma può essere disinstallato.
Per compilare la tua app, sono necessari gradle e firma apk. Puoi ricercarlo o utilizzare APK Builder per Android. È semplicissimo.
Ora che comprendiamo lo sviluppo di Android, creiamo i file e le cartelle.
Crea i file e le cartelle come ho discusso sopra. La mia directory apparirà come segue:
Ricorda che se stai usando un ide come Android Studio potrebbe avere un file di progetto.
A: NumPad / res / layout / key_preview.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="@android:color/white"
android:textColor="@android:color/black"
android:textSize="30sp">
</TextView>
B: NumPad / res / layout / keyboard_view.xml
<?xml version="1.0" encoding="utf-8"?>
<android.inputmethodservice.KeyboardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/keyboard_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:keyPreviewLayout="@layout/key_preview"
android:layout_alignParentBottom="true">
</android.inputmethodservice.KeyboardView>
C: NumPad / res / xml / method.xml
<?xml version="1.0" encoding="utf-8"?>
<input-method xmlns:android="http://schemas.android.com/apk/res/android">
<subtype android:imeSubtypeMode="keyboard"/>
</input-method>
D: Numpad / res / xml / number_pad.xml
<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="20%p"
android:horizontalGap="5dp"
android:verticalGap="5dp"
android:keyHeight="60dp">
<Row>
<Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"/>
<Key android:codes="50" android:keyLabel="2"/>
<Key android:codes="51" android:keyLabel="3"/>
<Key android:codes="52" android:keyLabel="4"/>
<Key android:codes="53" android:keyLabel="5" android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:codes="54" android:keyLabel="6" android:keyEdgeFlags="left"/>
<Key android:codes="55" android:keyLabel="7"/>
<Key android:codes="56" android:keyLabel="8"/>
<Key android:codes="57" android:keyLabel="9"/>
<Key android:codes="48" android:keyLabel="0" android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:codes="-5"
android:keyLabel="DELETE"
android:keyWidth="40%p"
android:keyEdgeFlags="left"
android:isRepeatable="true"/>
<Key android:codes="10"
android:keyLabel="ENTER"
android:keyWidth="60%p"
android:keyEdgeFlags="right"/>
</Row>
</Keyboard>
Ovviamente questo può essere facilmente modificato a proprio piacimento. Puoi anche usare immagini invece di parole per l'etichetta.
Suragch non ha dimostrato i file nella cartella dei valori e ha supposto che avessimo accesso ad Android Studio; che li crea automaticamente. Per fortuna ho APK Builder.
E: NumPad / res / values / colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
</resources>
F: NumPad / res / values / strings.xml
<resources>
<string name="app_name">Suragch NumPad</string>
</resources>
G: NumPad / res / values / styles.xml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
<!-- Customize your theme here. -->
</style>
</resources>
H: tastierino numerico / AndroidManifest.xml
Questo è il file che era davvero in discussione. Qui ho sentito che non avrei mai compilato il mio programma. singhiozzare. singhiozzare. Se controlli la risposta di Suracgh, vedrai che lascia il primo gruppo di campi vuoto e aggiunge il tag attività in questo file. Come ho detto, esistono quattro tipi di programmi Android. Un'attività è un'app normale con un'icona di avvio. Questo tastierino numerico non è un'attività! Inoltre non ha implementato alcuna attività.
I miei amici non includono il tag attività. Il tuo programma verrà compilato e quando proverai ad avviarlo andrà in crash! Per quanto riguarda xmlns: android e uses-sdk; Non posso aiutarti. Prova le mie impostazioni se funzionano.
Come puoi vedere c'è un codice di matricola, che lo registra come servizio. Anche service.android:name deve essere il nome della classe pubblica che estende il servizio nel nostro file java. DEVE essere capitalizzato di conseguenza. Inoltre pacchetto è il nome del pacchetto che abbiamo dichiarato nel file java.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="Saragch.num_pad">
<uses-sdk
android:minSdkVersion="12"
android:targetSdkVersion="27" />
<application
android:allowBackup="true"
android:icon="@drawable/Suragch_NumPad_icon"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<service
android:name=".MyInputMethodService"
android:label="Keyboard Display Name"
android:permission="android.permission.BIND_INPUT_METHOD">
<intent-filter>
<action android:name="android.view.InputMethod"/>
</intent-filter>
<meta-data
android:name="android.view.im"
android:resource="@xml/method"/>
</service>
</application>
</manifest>
I: NumPad / src / Saragch / num_pad / MyInputMethodService.java
Nota: penso che java sia un'alternativa a src.
Questo era un altro file problematico ma non così controverso come il file manifest. Dato che conosco Java abbastanza bene da sapere cosa è cosa e cosa non lo è. Conosco a malapena XML e come si lega allo sviluppo di Android!
Il problema qui era che non importava nulla! Voglio dire, ci ha fornito un file "completo" che utilizza nomi che non possono essere risolti! InputMethodService, Keyboard, ecc. Questa è una cattiva pratica, signor Suragch. Grazie per avermi aiutato, ma come ti aspettavi la compilazione del codice se i nomi non possono essere risolti?
Di seguito è riportata la versione modificata correttamente. Mi è capitato di cogliere un paio di suggerimenti per portarmi nel posto giusto per imparare cosa esattamente importare.
package Saragch.num_pad;
import android.inputmethodservice.InputMethodService;
import android.inputmethodservice.KeyboardView;
import android.inputmethodservice.Keyboard;
import android.text.TextUtils;
import android.view.inputmethod.InputConnection;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class MyInputMethodService extends InputMethodService implements KeyboardView.OnKeyboardActionListener
{
@Override
public View onCreateInputView()
{
// get the KeyboardView and add our Keyboard layout to it
KeyboardView keyboardView = (KeyboardView)getLayoutInflater().inflate(R.layout.keyboard_view, null);
Keyboard keyboard = new Keyboard(this, R.xml.number_pad);
keyboardView.setKeyboard(keyboard);
keyboardView.setOnKeyboardActionListener(this);
return keyboardView;
}
@Override
public void onKey(int primaryCode, int[] keyCodes)
{
InputConnection ic = getCurrentInputConnection();
if (ic == null) return;
switch (primaryCode)
{
case Keyboard.KEYCODE_DELETE:
CharSequence selectedText = ic.getSelectedText(0);
if (TextUtils.isEmpty(selectedText))
{
// no selection, so delete previous character
ic.deleteSurroundingText(1, 0);
}
else
{
// delete the selection
ic.commitText("", 1);
}
ic.deleteSurroundingText(1, 0);
break;
default:
char code = (char) primaryCode;
ic.commitText(String.valueOf(code), 1);
}
}
@Override
public void onPress(int primaryCode) { }
@Override
public void onRelease(int primaryCode) { }
@Override
public void onText(CharSequence text) { }
@Override
public void swipeLeft() { }
@Override
public void swipeRight() { }
@Override
public void swipeDown() { }
@Override
public void swipeUp() { }
}
Compila e firma il tuo progetto.
È qui che non ho idea come sviluppatore Android. Mi piacerebbe impararlo manualmente, poiché credo che i veri programmatori possano compilare manualmente.
Penso che gradle sia uno degli strumenti per la compilazione e il packaging in apk. apk sembra essere come un file jar o un rar per file zip. Esistono quindi due tipi di firma. chiave di debug che non è consentita su Play Store e chiave privata.
Bene, diamo una mano al signor Saragch. E grazie per aver guardato il mio video. Mi piace, iscriviti.
Ho avuto lo stesso problema. All'inizio ho usato il layout della tabella, ma il layout ha continuato a cambiare dopo aver premuto un pulsante. Ho trovato questa pagina molto utile però. http://mobile.tutsplus.com/tutorials/android/android-user-interface-design-creating-a-numeric-keypad-with-gridlayout/