Propósito del artículo.
Este artículo discutirá los problemas del desarrollo de Android y el desarrollo en general. Todos sabemos que desarrollar un programa es mucho trabajo difícil, que requiere mucho tiempo y esfuerzo, y a veces lleva mucho tiempo encontrar una solución a un problema, porque algunas soluciones de Internet no siempre funcionan.
Este artículo abordará los siguientes problemas:
- Teclado personalizado para Android
- Multithreading
- Integración de publicidad en el programa.
Teclado personalizado para Android
En mi programa, en mi calculadora tuve que hacer mi propio teclado, porque ingresar fórmulas matemáticas desde el teclado del sistema es extremadamente incómodo. Intentando resolver este problema, subí a un montón de foros, probé varias soluciones diferentes, pero todas no dieron el resultado deseado.
Comencemos:- Crea un nuevo proyecto en Android Studio.
- Vamos a crear un par de clases.
- Probar la aplicación
Hagamos un teclado simple de 9 caracteres con la capacidad de eliminar estos caracteres.
Pongamos nombre a nuestro proyecto KeyBoardTest

Elige una actividad vacía y comienza

Hecho, hemos creado nuestro nuevo proyecto. Ahora trataremos con el más básico, es decir, crear un archivo de diseño en la carpeta - res / layout y llamarlo teclado, aquí tendremos la apariencia del teclado.
Dibujemos este teclado:
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_gravity="bottom" android:background="@color/colorBlue" android:layout_width="match_parent" android:layout_height="100dp" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal"> <TextView android:id="@+id/one" android:textColor="@color/colorWhite" android:gravity="center" android:textSize="30sp" android:text="@string/one" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> <TextView android:id="@+id/two" android:textColor="@color/colorWhite" android:gravity="center" android:textSize="30sp" android:text="@string/two" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> <TextView android:id="@+id/three" android:textColor="@color/colorWhite" android:gravity="center" android:textSize="30sp" android:text="@string/three" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> <TextView android:id="@+id/four" android:textColor="@color/colorWhite" android:gravity="center" android:textSize="30sp" android:text="@string/four" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> <TextView android:id="@+id/five" android:textColor="@color/colorWhite" android:gravity="center" android:textSize="30sp" android:text="@string/five" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal"> <TextView android:id="@+id/six" android:textColor="@color/colorWhite" android:gravity="center" android:textSize="30sp" android:text="@string/six" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> <TextView android:id="@+id/seven" android:textColor="@color/colorWhite" android:gravity="center" android:textSize="30sp" android:text="@string/seven" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> <TextView android:id="@+id/eight" android:textColor="@color/colorWhite" android:gravity="center" android:textSize="30sp" android:text="@string/eight" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> <TextView android:id="@+id/nine" android:textColor="@color/colorWhite" android:gravity="center" android:textSize="30sp" android:text="@string/nine" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> <TextView android:id="@+id/delete" android:textColor="@color/colorWhite" android:gravity="center" android:textSize="30sp" android:text="@string/delete" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent"/> </LinearLayout> </LinearLayout> </FrameLayout>
Después de dibujar nuestro teclado, podemos crear una clase que registrará todas nuestras pulsaciones de teclado y escribirá lo que necesitamos. Tenga en cuenta que cada vista de texto tiene una identificación, ¡esto es muy importante!
Llame a esta clase KeyBoardListener.
Escribimos el constructor de nuestra clase, toma View como argumento: el campo en el que estamos trabajando, en otras palabras, la ubicación de nuestro editText, y también toma editText, en el que imprimiremos caracteres desde nuestro teclado.
package keyboard.develop.keyboardtest; import android.view.View; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; public class KeyBoardListener { EditText editText; private StringBuilder finalText = new StringBuilder(); KeyBoardListener(View view, final EditText editText) { this.editText = editText; TextView one = view.findViewById(R.id.one); TextView two = view.findViewById(R.id.two); TextView three = view.findViewById(R.id.three); TextView four = view.findViewById(R.id.four); final TextView five = view.findViewById(R.id.five); TextView six = view.findViewById(R.id.six); TextView seven = view.findViewById(R.id.seven); TextView eight = view.findViewById(R.id.eight); TextView nine = view.findViewById(R.id.nine); TextView delete = view.findViewById(R.id.delete); final LinearLayout layout = view.findViewById(R.id.keyBoard); one.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int selection = editText.getSelectionEnd(); finalText.insert(selection, "1"); setTextSelection(); } }); two.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int selection = editText.getSelectionEnd(); finalText.insert(selection, "2"); setTextSelection(); } }); three.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int selection = editText.getSelectionEnd(); finalText.insert(selection, "3"); setTextSelection(); } }); four.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int selection = editText.getSelectionEnd(); finalText.insert(selection, "4"); setTextSelection(); } }); five.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int selection = editText.getSelectionEnd(); finalText.insert(selection, "5"); setTextSelection(); } }); six.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int selection = editText.getSelectionEnd(); finalText.insert(selection, "6"); setTextSelection(); } }); seven.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int selection = editText.getSelectionEnd(); finalText.insert(selection, "7"); setTextSelection(); } }); eight.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int selection = editText.getSelectionEnd(); finalText.insert(selection, "8"); setTextSelection(); } }); nine.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int selection = editText.getSelectionEnd(); finalText.insert(selection, "9"); setTextSelection(); } }); delete.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { int selection = editText.getSelectionEnd(); if (finalText.length() > 0) { finalText = stringToBuilder(finalText.substring(0, selection - 1 == -1 ? 0 : selection - 1) + finalText.substring(selection)); editText.setText(finalText); } editText.setSelection(selection - 1 <= 0 ? 0 : selection - 1); } }); editText.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { layout.setVisibility(View.VISIBLE); } }); } private StringBuilder stringToBuilder(String s) { return new StringBuilder(s); } private void setTextSelection() { int selection = editText.getSelectionEnd(); editText.setText(finalText); editText.setSelection(selection + 1); } }
Ahora considere este código en detalle. Pasamos editText y view al propio constructor para tomar los botones y asignarles entrada. Cabe señalar que el método del botón Eliminar utiliza "azúcar sintáctico", en otras palabras, es una entrada de código abreviada. No todos conocen este diseño, así que decidí que deberíamos prestarle atención. Esto puede ser especialmente útil para principiantes.
Este diseño funciona de esta manera.
int p = () ? 1 : 2; int p = k == 2 ? 7 : 3;
Pero nos alejamos del tema. Ahora, después de que nuestro constructor esté listo, y podamos responder a los clics de los botones, podemos usar nuestra clase. Primero necesitamos llamar a esta clase en nuestra actividad principal
package keyboard.develop.keyboardtest; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.view.View; import android.view.WindowManager; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; public class MainActivity extends AppCompatActivity { private LinearLayout layout; private ExecutorThread executorThread; @Override protected void onCreate(Bundle savedInstanceState) { getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
Vale la pena prestar atención a esta línea.
getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
En esta línea, apagamos el teclado del sistema, pero al mismo tiempo dejamos el cursor para que podamos movernos entre los caracteres e insertar números / letras, etc. Esto es precisamente por qué utilizamos la clase
StringBuilder y el método de
inserción en el código anterior.
Debido al hecho de que todo este método se llama como una clase separada, podemos agregarlo en cualquier lugar y usarlo en cualquier programa. Así, se obtiene la objetividad del código.
Pero no le mostré cómo hacer esto en código xml, cómo decirnos la ubicación de este teclado, y todo es muy simple
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="keyboard.develop.keyboardtest.MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:textColor="@color/colorPrimary" android:gravity="center" android:textSize="25sp" android:layout_width="match_parent" android:layout_height="50dp" android:text="Write your text here!"/> <EditText android:id="@+id/edit" android:layout_width="match_parent" android:layout_height="50dp"/> </LinearLayout> <LinearLayout // android:visibility="gone" android:id="@+id/keyBoard" android:layout_height="wrap_content" android:layout_width="match_parent" android:layout_gravity="bottom"> <include layout="@layout/keyboard"/> // , </LinearLayout> </FrameLayout>
Ahora, con manipulaciones fáciles, podemos usar nuestros teclados en cualquier lugar, incluso en fragmentos.
En nuestra aplicación, el teclado se ve así

Multithreading
Multithreading: el nombre implica que hay muchos hilos. Y muchos subprocesos, esto significa realizar varias operaciones simultáneamente. El subprocesamiento múltiple es un tema bastante problemático en la programación. Qué en C ++, qué en Java, qué otros lenguajes con subprocesos múltiples siempre tuvieron problemas. Afortunadamente, casi todos los idiomas tienen una solución de alto nivel para este problema. Pero actualmente estamos desarrollando para Android, por lo que hablaremos sobre Anroid, y más específicamente sobre el lenguaje de programación Java.
En Java YP existe un tema como Thread: es conveniente para dibujar, con un frecuente rediseño instantáneo de la imagen, hay muchos artículos sobre este tema, incluido Habré, por lo que no consideraré esta opción. Estoy interesado en la llamada "corriente de quedarse dormido", una corriente que está esperando su llamada para resolver una tarea en particular. Este es el caso cuando llamó a un hilo, funcionó y se quedó dormido, sin desperdiciar recursos del dispositivo mientras esperaba una nueva tarea.
Y el nombre de lo que describí anteriormente es una clase del paquete estándar java.util.concurrent
ExecutorServiseLa esencia de esta clase es que puede reutilizar el mismo hilo sin crear uno nuevo. Y ahora consideraremos cómo funciona, no crearemos un nuevo programa, sino que seguiremos trabajando en el nuestro.
Para hacer esto, cree una nueva clase, que se llamará ExecutorThread. Planteamos el problema de que necesitamos agregar uno al dígito
p hasta que esta
p sea igual al número que introdujimos en 4 grados. Todo se hace para que el cálculo sea más largo. Y para que toda la interfaz no se congele, lo pondremos todo en un hilo separado.
package keyboard.develop.keyboardtest; import android.widget.TextView; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ExecutorThread { private ExecutorService executorService; private Thread thread; private int p = 0; private int pow = 0; private int k = 0; private TextView textView; ExecutorThread(final TextView text) { p = 0; textView = text; thread = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < pow; i++) p++; String s = "Result " + k + "^4 = " + String.valueOf(p); textView.setText(s); } }); thread.start(); executorService = Executors.newSingleThreadExecutor(); } void doWork() { executorService.submit(thread); } void setK(int k) { p = 0; this.k = k; pow = (int) Math.pow(k, 4); textView.setText("Please wait. We are calcing!"); } }
Como podemos ver, en ese momento, aunque todavía no hemos contado, vemos la entrada "Por favor, espere. ¡Estamos calzando! ”, Lo cual está claro:“ Por favor, espere. ¡Contamos! Y después de contar, enviaremos el texto a nuestro textView, que pasamos al constructor de nuestra clase. Para que todo funcione, debemos agregar textView después de nuestro editText a nuestra activity_main, que teníamos al crear el proyecto.
<TextView android:gravity="center" android:textColor="@color/colorPrimary" android:textSize="25sp" android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="50dp"/>
Y también necesitamos agregar el siguiente código a nuestra clase principal: MainActivity.
executorThread = new ExecutorThread((TextView)findViewById(R.id.textView)); editText.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {} @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {} @Override public void afterTextChanged(Editable editable) { if (!editable.toString().equals("")) { executorThread.setK(Integer.parseInt(editText.getText().toString())); executorThread.doWork(); } } });
Vale la pena señalar que el método addTextChangeListener es responsable de cambiar el texto en nuestro editText. Como vemos, dentro del método, llamamos a la función doWork (), que a su vez ejecuta estas líneas
executorService.submit(thread);
Verifiqué todo lo anterior en mi teléfono, así que si hiciste todo bien, entonces no deberías tener problemas o errores.
Como podemos ver, este método es bastante conveniente y fácil de entender, traté de describir todo lo más simple posible, así que espero que todo esté claro para usted, pero no me he perdido nada.
Y ahora, pasemos al punto 3 de nuestro artículo, a saber, la integración de la publicidad.
Integración de anuncios
De hecho, no puedo hablar mucho sobre esto, solo puedo aconsejar. Con la publicidad, no todo es tan fácil y transparente. Personalmente, le aconsejaría que use Appodeal, ha estado en el mercado no hace mucho tiempo, pero funciona con bastante éxito.
También vale la pena señalar que hay un muy buen soporte en ruso, que casi siempre responde a su pregunta o problema de inmediato. Esto inmediatamente deja en claro cuán leal es esta red.
Quiero decir de inmediato, si de repente lo usa, asegúrese de configurar el pago en AdMob y Appodeal, de lo contrario, el anuncio simplemente no se cargará. Debido al hecho de que no configuré las cuentas, desperdicié todo el día y luego me dijeron en apoyo: "¿He configurado las cuentas?" Y después de hacer esto, apareció un anuncio 2 horas después.
Conclusión
Dado que este artículo está destinado a programadores principiantes, quiero señalar una cosa obvia. Si realmente te gusta la programación y estás listo para pasar toneladas de horas resolviendo un problema en particular, entonces la programación es tuya, de lo contrario no. Además, no vayas más allá. Como la solución también es demasiado larga, algo no demasiado complicado ni demasiado simple no es bueno. Pero este es un hecho obvio. De hecho, leí esta frase en algún lugar de Internet. De hecho, es verdad. Si lo piensas, entonces realmente, si la programación, la programación seria sería tan fácil, entonces una pequeña parte de las personas del número total de todas las personas no se involucrarían en ella.
Espero que mi artículo haya sido útil para alguien y realmente haya ayudado a alguien, me ayudó a ahorrar tiempo, porque personalmente eliminé algo tan simple en el teclado, me pareció como 3 días, y me llevó 2 días buscar y encontrar una solución normal del día