Vamos a programar #37 - DecToAny, Versión java (Android).

Hola a todos, el día de hoy vamos a ver una tercera entrega de la aplicación DecToAny, en los últimos dos post, vimos cómo crear una versión para Windows (hecha en C#), una versión para la web (hecha en javascript) y finalmente el día de hoy vamos a ver una versión para Android (hecha en Java).

Creando la interfaz.

La interfaz principal está compuesta por 4 componentes:
  • 1 TextView.
  • 1 EditText (Numérico).
  • 1 Button.
  • 1 ListView.
Todos los componentes se pueden crear con el siguiente código:

 <?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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="com.mdev.com.dectoany.MainActivity">

	<LinearLayout
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:orientation="vertical"
		tools:layout_editor_absoluteX="8dp"
		tools:layout_editor_absoluteY="8dp">

		<TextView
			android:id="@+id/lblNumberIn"
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:text="Número a convertir" />

		<EditText
			android:id="@+id/TXTNumberIn"
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:ems="10"
			android:inputType="number" />

		<Button
			android:id="@+id/BtnConvert"
			android:layout_width="match_parent"
			android:layout_height="wrap_content"
			android:text="Convertir" />

		<ListView
			android:id="@+id/LVResults"
			android:layout_width="match_parent"
			android:layout_height="match_parent" />
	</LinearLayout>
</android.support.constraint.ConstraintLayout>

Con esto, tendremos todos los controles necesarios para que el usuario interactue con la aplicación, ahora solo queda implementar el código que hace funcionar las cosas.

El Código que hace funcionar las cosas.

El código es muy parecido al que usamos para la versión de C#. Solo que en este caso, vamos a usar el control ListView para mostrar los resultados de las conversiones.
El código java de DecToAny es el siguiente:

package com.mdev.com.dectoany;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MainActivity extends Activity {

	Button BtnConvert;
	ListView LVResults;
	TextView TxtNumberIn;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		BtnConvert = (Button) findViewById(R.id.BtnConvert);
		TxtNumberIn = (TextView) findViewById(R.id.TXTNumberIn);
		LVResults = (ListView) findViewById(R.id.LVResults);

		BtnConvert.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {
				DoConvert();
			}
		});
	}

	private void DoConvert(){
		ArrayList Items = new ArrayList();
		String CurrentNumber = TxtNumberIn.getText().toString();
		int MyNumber = Integer.parseInt(CurrentNumber);
		for (int I = 2; I < 30; I++){
			Items.add(ListToString(NumbersList(MyNumber, I))+"\n"+"Base "+ I);
		}
		final ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1,Items);
		LVResults.setAdapter(adapter);
	}
	private String ListToString(List<Integer> Numbers)
	{
		Collections.reverse(Numbers);
		String Result = "";
		for (int i = 0; i < Numbers.size(); i++){
			int CurrentNumber = Numbers.get(i);
			if (CurrentNumber < 10)
				Result += CurrentNumber;
			else
				Result += NumberToChar(Numbers.get(i));
		}
		return Result;
	}
	private char NumberToChar(int Number){
			return (char)(Number + 55);
	}

	private List<Integer> NumbersList(Integer InNumber, int Base) {
		Integer LastNumber = InNumber;
		Integer Garbage;
		List<Integer> result = new ArrayList<Integer>();
		if (LastNumber < Base) {
			result.add(LastNumber);
		}
		else         {
			if (LastNumber >= Base) {
				do {
					Garbage = LastNumber % Base;
					LastNumber = LastNumber / Base;
					if (LastNumber < Base) {
						result.add(Garbage);
						result.add(LastNumber);
					} else {
						result.add(Garbage);
					}
				} while (LastNumber >= Base);
			}
		}
		return result;
	}
}

Para esta aplicación vamos usar 4 funciones, la primera de ellas en orden de uso (no de aparicion) es "NumberList", esta es la función que va a realizar los cálculos; cómo parámetros de entrada, recibirá un parámetro del tipo "Integer" llamado "InNumber" que es el número decimal que queremos convertir; seguido de una valor del tipo "int" llamado "Base", este; cómo su nombre lo indica; es la base de destino a la cual queremos convertir nuestro número decimal. La función regresa una lista del tipo "List<Integer>" con los valores de los dígitos para formar el número, pero en orden inverso.
Después tenemos la función "ListToString" que será la encargada de formar un número y devolverlo en forma de "String". Esta función recibe cómo parámetro un lista del tipo "List<Integer>". Esta función se encarga primero; en invertir el orden de la lista que se ingresa cómo parámetro. Después comprueba si el valor es menor a 10 (decimal), si es así, simplemente agrega al string "Result" (variable interna de la función) el valor actual, en caso contrario, manda a llamar a la función "NumberToChar" que se encargara de asignar una letra de la A a la Z a los valores mayores a 10. Finalmente devuelve un "string" que contiene la representación de los resultados de la función "NumberToList" en el formato adecuado para que cualquier persona lo pueda entender.
La función "NumberToChar" simplemente devuelve el numero que se ingresa cómo parámetro + 55.
Para la aplicación de Android también usamos un procedimiento llamado "DoConvert"; en el cual se manda a llamar a las otras funciones dentro de un bucle que va del 2 al 29. En este procedimiento se crea un "ArrayAdapter" que se llenará con los valores que se crean en el ciclo "for" y finalmente se asignan al "ListView".
Con esto podemos obtener de forma fácil el valor de un numero decimal en 27 bases diferentes. En todas las aplicaciones (Android, Windows, Web)no he revisado los errores que puedan haber, no porque sea perezoso o algo similar), pero un error critico existe en la version Web, en esta al poder escoger cual es la base a la que queremos convertir nuestro numero, podemos introducir base 1, pero esta base es imposible de usar, ya que solo disponemos del numero 0, entonces al hacer las divisiones, entramos al bucle "while", pero nunca podremos salir de el, y en algún momento la memoria se acabará hasta que finalmente el navegador en el cual se usa falle. Aunque el sentido común dice que no se debe de hacer lo antes descrito, nunca falta aquel que lo haga solo para saber que pasa. Para evitarlo basta con comprobar las base de destino, si es menor a 2, simplemente hay que informarle al usuario y terminar la ejecución.
Y bien, por ahora es todo, la aplicación compilada la puedes descargar de mi dropbox, el código lo subiré un poco después, primero voy a corregir un error minusculo en el proyecto. (Debería de ser com.mdev.dectoany, en su lugar puse com.mdev.com.dectoany ).

Los leo luego

No hay comentarios.