Quiero hacer un teclado personalizado. No sé cómo hacerlo usando XML y Java. La siguiente imagen es un modelo del teclado que quiero hacer. Solo necesita números.
Quiero hacer un teclado personalizado. No sé cómo hacerlo usando XML y Java. La siguiente imagen es un modelo del teclado que quiero hacer. Solo necesita números.
Respuestas:
En primer lugar, necesitará un keyboard.xml
archivo que se colocará en la res/xml
carpeta (si la carpeta no existe, créelo).
<?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>
** Tenga en cuenta que tendrá que crear el backspace
dibujable y colocarlo en la carpeta res / drawable-ldpi con un tamaño muy pequeño (como 18x18 píxeles)
Luego, en el archivo xml que desea que se use (donde se encuentra su TextView), debe agregar el siguiente código:
<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>
** Tenga en cuenta que el archivo xml en el que colocará el android.inputmethodservice.KeyboardView
, debe ser RelativeLayout
para poder configurar el alignParentBottom="true"
(por lo general, los teclados se presentan en la parte inferior de la pantalla)
Luego, debe agregar el siguiente código en la onCreate
función del Activity
que maneja el TextView
que desea adjuntar el teclado
// 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);
** Tenga en cuenta que mKeyboard
y mKeyboardView
son variables de clase privadas que debe crear.
Entonces necesita la siguiente función para abrir el teclado (debe asociarlo con TextView a través de la onClick
propiedad 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);
}
Y finalmente necesitas el OnKeyboardActionListener
que se encargará de tus eventos.
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() {
}
};
¡¡¡Espero que ayude!!!
La mayor parte del código que se encuentra aquí
Esta respuesta le dice cómo hacer un teclado de sistema personalizado que se pueda usar en cualquier aplicación que un usuario haya instalado en su teléfono. Si desea hacer un teclado que solo se usará dentro de su propia aplicación, vea mi otra respuesta .
El siguiente ejemplo se verá así. Puede modificarlo para cualquier distribución de teclado.
Los siguientes pasos muestran cómo crear un teclado de sistema personalizado que funcione. En la medida de lo posible, intenté eliminar cualquier código innecesario. Si hay otras funciones que necesita, al final proporcioné enlaces para obtener más ayuda.
Llamé a mi proyecto "Teclado personalizado". Llámalo como quieras. No hay nada más especial aquí. Solo dejaré MainActivity
y "¡Hola mundo!" diseño como está.
Agregue los siguientes dos archivos a su aplicación res/layout
carpeta de :
keyboard_view.xml
Esta vista es como un contenedor que contendrá nuestro teclado. En este ejemplo, solo hay un teclado, pero puede agregar otros teclados e intercambiarlos dentro y fuera de este 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
La vista previa de la tecla es un diseño que aparece cuando presiona una tecla del teclado. Solo muestra qué tecla está presionando (en caso de que sus dedos grandes y gordos la cubran). Esta no es una ventana emergente de opción múltiple. Para eso, debe consultar la vista de candidatos .
<?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
carpeta en tu res
carpeta. (Haga clic derecho res
y elija Nuevo> Directorio ).
Luego agregue los siguientes dos archivos xml. (Haga clic con el botón derecho en la xml
carpeta y elija Nuevo> Archivo de recursos XML ).
number_pad.xml
Aquí es donde comienza a ponerse más interesante. Esto Keyboard
define el diseño de las claves .
<?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>
Aquí hay algunas cosas a tener en cuenta:
keyWidth
: Este es el ancho predeterminado de cada tecla. Esto 20%p
significa que cada tecla debe ocupar el 20% del ancho de la p arent. Sin embargo, se puede anular con teclas individuales, como puede ver que sucedió con las teclas Eliminar e Intro en la tercera fila.keyHeight
: Está codificado aquí, pero podría usar algo como @dimen/key_height
configurarlo dinámicamente para diferentes tamaños de pantalla.Gap
: El espacio horizontal y vertical indica cuánto espacio dejar entre las teclas. Incluso si lo configura en0px
todavía hay un pequeño espacio.codes
: Puede ser un valor de código Unicode o personalizado que determina qué sucede o qué se ingresa cuando se presiona la tecla. Vea keyOutputText
si desea ingresar una cadena Unicode más larga.keyLabel
: Este es el texto que se muestra en la tecla.keyEdgeFlags
: Esto indica con qué borde debe alinearse la llave.isRepeatable
: Si mantiene presionada la tecla, seguirá repitiendo la entrada.método.xml
Este archivo le dice al sistema los subtipos de métodos de entrada que están disponibles. Solo incluyo una versión mínima aquí.
<?xml version="1.0" encoding="utf-8"?>
<input-method
xmlns:android="http://schemas.android.com/apk/res/android">
<subtype
android:imeSubtypeMode="keyboard"/>
</input-method>
Cree un nuevo archivo Java. Vamos a llamarlo MyInputMethodService
. Este archivo une todo. Maneja la entrada recibida del teclado y la envía a cualquier vista que la reciba (una EditText
, por ejemplo).
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() { }
}
Notas:
OnKeyboardActionListener
escucha la entrada del teclado. También requiere todos esos métodos vacíos en este ejemplo.InputConnection
es lo que se utiliza para enviar la entrada a otra vista como una EditText
.Pongo esto último en lugar de primero porque se refiere a los archivos que ya agregamos anteriormente. Para registrar su teclado personalizado como un teclado del sistema, debe agregar una service
sección a su archivo AndroidManifest.xml . Ponlo en la application
sección siguiente 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>
¡Eso es! Debería poder ejecutar su aplicación ahora. Sin embargo, no verá mucho hasta que habilite su teclado en la configuración.
Todos los usuarios que quieran usar su teclado deberán habilitarlo en la configuración de Android. Para obtener instrucciones detalladas sobre cómo hacerlo, consulte el siguiente enlace:
He aquí un resumen:
Ahora debería poder usar su teclado en cualquier lugar donde pueda escribir en Android.
El teclado de arriba es utilizable, pero para crear un teclado que otras personas quieran usar, probablemente tendrá que agregar más funciones. Estudie los enlaces a continuación para aprender cómo.
No me gusta como el estándar KeyboardView
ve y se comporta ? Ciertamente no lo hago. Parece que no se ha actualizado desde Android 2.0. ¿Qué tal todos esos teclados personalizados en Play Store? No se parecen en nada al feo teclado de arriba.
La buena noticia es que puede personalizar completamente el aspecto y el comportamiento de su propio teclado. Deberá hacer lo siguiente:
ViewGroup
. Puede llenarlo con Button
s o incluso crear sus propias vistas clave personalizadas para esa subclase View
. Si usa vistas emergentes, tenga en cuenta esto .onKeyClicked(String text)
o onBackspace()
.keyboard_view.xml
, key_preview.xml
o se number_pad.xml
describe en las instrucciones anteriores, ya que estos son todos para elKeyboardView
. Manejará todos estos aspectos de la interfaz de usuario en su vista personalizada.MyInputMethodService
clase, implemente el oyente de teclado personalizado que definió en su clase de teclado. Esto está en lugar de KeyboardView.OnKeyboardActionListener
, que ya no es necesario.MyInputMethodService
el onCreateInputView()
método de su clase , cree y devuelva una instancia de su teclado personalizado. No olvide configurar el oyente personalizado del teclado en this
.Esta respuesta le dice cómo hacer un teclado personalizado para usar exclusivamente dentro de su aplicación. Si desea crear un teclado de sistema que se pueda usar en cualquier aplicación, consulte mi otra respuesta .
El ejemplo se verá así. Puede modificarlo para cualquier distribución de teclado.
Nombré mi proyecto InAppKeyboard
. Llama al tuyo como quieras.
Diseño del teclado
Agregue un archivo de diseño a la res/layout
carpeta. Llamé al mío keyboard
. El teclado será una vista compuesta personalizada que inflaremos a partir de este archivo de diseño xml. Puede usar el diseño que desee para organizar las claves, pero estoy usando un archivo LinearLayout
. Tenga en cuenta las merge
etiquetas.
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>
Diseño de actividad
Para fines de demostración nuestra actividad tiene un solo EditText
y el teclado está en la parte inferior. Llamé a mi vista de teclado personalizadaMyKeyboard
. (Agregaremos este código pronto, así que ignore el error por ahora). La ventaja de poner todo el código de nuestro teclado en una sola vista es que facilita su reutilización en otra actividad o aplicación.
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>
Agregue un nuevo archivo Java. Llamé al mío MyKeyboard
.
Lo más importante a tener en cuenta aquí es que no hay un vínculo físico a ninguno EditText
o Activity
. Esto facilita su conexión a cualquier aplicación o actividad que lo necesite. Esta vista de teclado personalizado también utiliza un InputConnection
, que imita la forma en que un teclado del sistema se comunica con un EditText
. Así es como evitamos los enlaces duros.
MyKeyboard
es una vista compuesta que infla el diseño de vista que definimos anteriormente.
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;
}
}
Para los teclados del sistema, Android usa un InputMethodManager para apuntar el teclado al foco EditText
. En este ejemplo, la actividad ocupará su lugar proporcionando el enlace desde el EditText
a nuestro teclado personalizado a.
Como no estamos usando el teclado del sistema, debemos desactivarlo para evitar que aparezca cuando tocamos EditText
. En segundo lugar, necesitamos obtener el InputConnection
del EditText
y dárselo a nuestro teclado.
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);
}
}
Si su actividad tiene varios EditTexts, deberá escribir código para pasar los EditText correctos InputConnection
al teclado. (Puede hacer esto agregando un OnFocusChangeListener
y OnClickListener
a EditTexts. Vea este artículo para una discusión de eso). También puede querer ocultar o mostrar su teclado en los momentos apropiados.
Eso es. Debería poder ejecutar la aplicación de ejemplo ahora e ingresar o eliminar texto como desee. El siguiente paso es modificar todo para adaptarlo a sus propias necesidades. Por ejemplo, en algunos de mis teclados he usado TextViews en lugar de Buttons porque es más fácil personalizarlos.
TextView
poco a Button
si desea que las claves se vean mejor. Luego, haga que el fondo sea un dibujable que cambie el estado de apariencia cuando se presiona.View
y teclados personalizados en esa subclase ViewGroup
. El teclado presenta todas las teclas mediante programación. Las teclas usan una interfaz para comunicarse con el teclado (similar a cómo los fragmentos se comunican con una actividad). Esto no es necesario si solo necesita un diseño de teclado único, ya que el diseño xml funciona bien para eso. Pero si quieres ver un ejemplo de lo que he estado trabajando, mira todas las clases Key*
y aquí . Tenga en cuenta que también utilizo una vista de contenedor cuya función es intercambiar teclados hacia adentro y hacia afuera.Keyboard*
InputMethodManager#showInputMethodPicker()
. Sin embargo, si el teclado original no tiene esa tecla, la única forma en que los usuarios pueden cambiar a su teclado es hacerlo manualmente en la configuración del sistema. Apple es superior a Android en esta área, porque Apple requiere que todos los teclados tengan una tecla de cambio de teclado.
EditText
s, deberá agregarles un valor onFocusChangedListener
para que, cuando reciban el foco, pueda asignarlos InputConnection
desde el actual EditText
a su teclado personalizado.
Utilizar KeyboardView
:
KeyboardView kbd = new KeyboardView(context);
kbd.setKeyboard(new Keyboard(this, R.xml.custom));
kbd.setOnKeyboardActionListener(new OnKeyboardActionListener() {
....
}
ahora tienes lo kbd
que es una vista normal.
Lo bueno de esto es que se R.xml.custom
refiere a /res/xml/custom.xml
, que define en xml la distribución del teclado. Para obtener más información sobre este archivo, busque aquí: Keyboard , Keyboard.Row , Keyboard.Key .
Aquí hay un proyecto de muestra para un teclado virtual.
https://developer.android.com/guide/topics/text/creating-input-method.html
El suyo debe estar en las mismas líneas con un diseño diferente.
Editar: Si necesita el teclado solo en su aplicación, ¡es muy simple! Cree un diseño lineal con orientación vertical y cree 3 diseños lineales en su interior con orientación horizontal. Luego coloque los botones de cada fila en cada uno de esos diseños lineales horizontales y asigne la propiedad de peso a los botones. Use android: layout_weight = 1 para todos ellos, para que estén igualmente espaciados.
Esto solucionará. Si no obtuvo lo que esperaba, publique el código aquí, ¡y estamos aquí para ayudarlo!
Uno de los mejores ejemplos bien documentados que encontré.
http://www.fampennings.nl/maarten/android/09keyboard/index.htm
KeyboardView
Se proporcionan archivos XML relacionados y código fuente.
Encontré esta publicación recientemente cuando estaba tratando de decidir qué método usar para crear mi propio teclado personalizado. Descubrí que la API del sistema Android era muy limitada, así que decidí crear mi propio teclado en la aplicación. Usando la respuesta de Suragch como base para mi investigación, continué diseñando mi propio componente de teclado . Está publicado en GitHub con una licencia MIT. Con suerte, esto le ahorrará a otra persona mucho tiempo y dolor de cabeza.
La arquitectura es bastante flexible. Hay una vista principal (CustomKeyboardView) que puede inyectar con cualquier distribución de teclado y controlador que desee.
Solo tiene que declarar CustomKeyboardView en su xml de actividad (también puede hacerlo mediante programación):
<com.donbrody.customkeyboard.components.keyboard.CustomKeyboardView
android:id="@+id/customKeyboardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" />
Luego registre su EditText con él y dígale qué tipo de teclado deben usar:
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 se encarga del resto!
Tengo la pelota rodando con un teclado numérico, numérico decimal y QWERTY. No dude en descargarlo y crear sus propios diseños y controladores. Se parece a esto:
Incluso si esta no es la arquitectura con la que decide ir, con suerte será útil ver el código fuente de un teclado en la aplicación que funcione.
Nuevamente, aquí está el enlace al proyecto: Teclado personalizado en la aplicación
Bueno, Suragch dio la mejor respuesta hasta ahora, pero omitió ciertas cosas menores que eran importantes para compilar la aplicación.
Espero dar una mejor respuesta que Suragch mejorando su respuesta. Agregaré todos los elementos que faltan que no puso.
Compilé mi apk usando la aplicación de Android, APK Builder 1.1.0. Vamos a empezar.
Para crear una aplicación de Android, necesitamos un par de archivos y carpetas que estén organizados en un formato determinado y en mayúsculas en consecuencia.
diseño res -> archivos xml que muestran cómo se verá la aplicación en el teléfono. Similar a cómo html da forma al aspecto de la página web en el navegador. Permitir que su aplicación se ajuste a las pantallas en consecuencia.
valores -> datos constantes como colors.xml, strings.xml, styles.xml. Estos archivos deben estar escritos correctamente.
dibujable -> imágenes {jpeg, png, ...}; Nómbrelos cualquier cosa.
mipmap -> más fotos. utilizado para el icono de la aplicación?
xml -> más archivos xml.
src -> actúa como JavaScript en html. Los archivos de diseño iniciarán la vista inicial y su archivo Java controlará dinámicamente los elementos de la etiqueta y los eventos de activación. Los eventos también se pueden activar directamente en layout.xml al igual que en html.
AndroidManifest.xml -> Este archivo registra de qué se trata su aplicación. Nombre de la aplicación, tipo de programa, permisos necesarios, etc. Esto parece hacer que Android sea bastante seguro. Los programas, literalmente, no pueden hacer lo que no pidieron en el Manifiesto.
Ahora hay 4 tipos de programas de Android: una actividad, un servicio, un proveedor de contenido y un receptor de transmisión. Nuestro teclado será un servicio que permitirá que se ejecute en segundo plano. No aparecerá en la lista de aplicaciones para iniciar; pero se puede desinstalar.
Para compilar su aplicación, implica la firma de Gradle y apk. Puedes investigar ese o usar APK Builder para Android. Es superfácil.
Ahora que entendemos el desarrollo de Android, creemos los archivos y carpetas.
Cree los archivos y carpetas como comenté anteriormente. Mi directorio se verá de la siguiente manera:
Recuerde que si está utilizando un ide como Android Studio, puede tener un archivo de proyecto.
R: 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: teclado numérico / 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>
Por supuesto, esto se puede editar fácilmente a su gusto. Incluso puede utilizar imágenes en lugar de palabras para la etiqueta.
Suragch no demostró los archivos en la carpeta de valores y asumió que teníamos acceso a Android Studio; que los crea automáticamente. Menos mal que tengo 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: teclado numérico / AndroidManifest.xml
Este es el archivo que realmente estaba en disputa. Aquí sentí que nunca compilaría mi programa. sollozo. sollozo. Si verifica la respuesta de Suracgh, verá que deja el primer conjunto de campos vacío y agrega la etiqueta de actividad en este archivo. Como dije, hay cuatro tipos de programas de Android. Una actividad es una aplicación normal con un icono de inicio. ¡Este teclado numérico no es una actividad! Además, no implementó ninguna actividad.
Mis amigos no incluyen la etiqueta de actividad. Su programa se compilará y, cuando intente ejecutarlo, se bloqueará. En cuanto a xmlns: android y uses-sdk; No puedo ayudarte en eso. Pruebe mi configuración si funciona.
Como puede ver, hay una etiqueta de servicio, que lo registra como un servicio. También service.android:name debe ser el nombre de la clase pública que extiende el servicio en nuestro archivo java. DEBE estar en mayúscula en consecuencia. También paquete es el nombre del paquete que declaramos en el archivo 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>
Yo: NumPad / src / Saragch / num_pad / MyInputMethodService.java
Nota: creo que java es una alternativa a src.
Este era otro archivo problemático pero no tan polémico como el archivo de manifiesto. Como sé Java lo suficientemente bueno como para saber qué es qué, qué no lo es. ¡Apenas conozco XML y cómo se relaciona con el desarrollo de Android!
¡El problema aquí era que no importaba nada! Quiero decir, ¡nos dio un archivo "completo" que usa nombres que no se pudieron resolver! InputMethodService, Keyboard, etc. Esa es una mala práctica, Sr. Suragch. Gracias por ayudarme, pero ¿cómo esperaba que se compilara el código si los nombres no se pueden resolver?
A continuación se muestra la versión correctamente editada. Simplemente me abalancé sobre un par de pistas que me llevaron al lugar correcto para saber qué importar exactamente.
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 y firma tu proyecto.
Aquí es donde no tengo ni idea como nuevo desarrollador de Android. Me gustaría aprenderlo manualmente, ya que creo que los programadores reales pueden compilar manualmente.
Creo que gradle es una de las herramientas para compilar y empaquetar en apk. apk parece ser como un archivo jar o un rar para un archivo zip. Entonces hay dos tipos de firma. clave de depuración que no está permitida en Play Store y clave privada.
Bueno, echemos una mano al Sr. Saragch. Y gracias por ver mi video. Me gusta, suscríbete.
Tuvo el mismo problema. Usé el diseño de la tabla al principio, pero el diseño siguió cambiando después de presionar un botón. Sin embargo, encontré esta página muy útil. http://mobile.tutsplus.com/tutorials/android/android-user-interface-design-creating-a-numeric-keypad-with-gridlayout/