Cuando empiezas a desarrollar en Android, uno de los primeros choques es entender cómo se construye la interfaz de usuario y cómo se conectan los elementos visuales con el código Java o Kotlin. En esta guía vas a ver, paso a paso, cómo funcionan los views básicos en XML (TextView, EditText y Button), cómo se organizan dentro de diferentes tipos de layouts y cómo hacer que reaccionen a las acciones del usuario (como pulsar un botón).
Vamos a ir desde lo más simple hasta cosas un poco más avanzadas: primero entender qué es una vista, luego cómo se describe todo en XML, después cómo se organiza con layouts como LinearLayout y RelativeLayout, y por último cómo capturar eventos y hacer cosas reales: leer textos, sumar números, mover datos entre actividades, etc. Todo explicado en castellano “de la calle”, pero sin perder el rigor técnico.
¿Qué es un View en Android y por qué todo empieza ahí?
En Android, cualquier cosa que veas en pantalla y con la que puedas interactuar es un View (vista). Da igual que sea un botón, un cuadro de texto, una imagen o un simple recuadro de color: todo deriva de la clase base android.view.View.
Encima de esa clase base se construye un montón de componentes ya preparados que usamos a diario: TextView para mostrar texto, EditText para introducir datos y Button para disparar acciones. Podrías extender directamente View y dibujarlo todo a mano, pero en el día a día casi nunca te interesa reinventar la rueda.
Junto a las vistas “simples” existen los contenedores, que son clases que heredan de ViewGroup. Un ViewGroup no muestra contenido en sí mismo, sino que se usa para organizar y posicionar otras vistas hijas. Ejemplos típicos son LinearLayout, RelativeLayout, FrameLayout o el más moderno ConstraintLayout.
La interfaz al final es una jerarquía de View y ViewGroup: los ViewGroup forman las ramas (layouts) y dentro se van colgando las vistas hijas (TextView, EditText, Button, ImageView, etc.). Eso es lo que acabas describiendo en XML cuando diseñas una pantalla.
Definir la interfaz en XML: layouts y activity
En una aplicación Android típica, cada pantalla se compone de dos piezas muy claras: un archivo de diseño XML y una clase de código (la Activity). El XML vive en la carpeta res/layout y se encarga de todo lo visual: qué vistas hay, cómo se distribuyen, qué textos muestran, etc. La Activity vive en java o kotlin y define la lógica, acciones y procesos que se ejecutan sobre esa interfaz.
Cuando creas un proyecto con plantillas tipo “Blank Activity”, Android Studio te genera, por ejemplo, un MainActivity y un layout por defecto llamado activity_main.xml. Esa Activity suele ser la primera que se ejecuta al abrir la app, así que es habitual considerarla el punto de entrada visual principal.
La conexión entre ambos mundos se hace en el método onCreate(). Dentro de ese método, se llama a setContentView(R.layout.activity_main), que le dice a la Activity: “usa este XML como interfaz de esta pantalla”. Desde ese momento, todas las vistas definidas en el XML se crean y puedes manipularlas desde código mediante sus IDs.
TextView, EditText y Button: los básicos que vas a usar siempre
TextView: mostrar texto en pantalla
Un TextView es el componente estándar para mostrar texto fijo o dinámico: mensajes al usuario, resultados, instrucciones, etiquetas de formularios, etc. Internamente simplemente pinta texto, pero permite cambiar tamaño (textSize), color (textColor), fuente (typeface), estilo (bold, italic), márgenes y muchas otras propiedades.
En el XML puedes declararlo tal que así:
<TextView
android:id="@+id/tv_resultado"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Resultado" />
La clave es el atributo android:id, que le asigna un identificador único dentro del layout. El prefijo @+id/ indica que estás creando ese ID por primera vez. Más tarde, desde la Activity, podrás usar ese ID para buscar la vista con findViewById(R.id.tv_resultado) y cambiar su texto mediante setText().
EditText: campos de entrada de datos
Si en lugar de mostrar texto quieres que el usuario pueda escribirlo, tienes que usar EditText. Es el cuadro de entrada clásico en el que se teclea un nombre, un email, una contraseña o cualquier otro dato. Se declara igual que un TextView, pero con la etiqueta <EditText> y con algunas propiedades extra.
Un ejemplo típico de EditText en un layout XML:
<EditText
android:id="@+id/edit_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/edit_message" />
El atributo android:hint sirve para mostrar un texto “fantasma” mientras el campo esté vacío, del estilo “Introduce un mensaje” o “Escribe tu nombre”. Este hint desaparece en cuanto el usuario comienza a escribir, lo que hace muy cómodo guiar la entrada de datos sin usar un TextView aparte.
Además, puedes usar variantes especializadas del propio diseñador, como el tipo “Number” (sigue siendo EditText por debajo), que fuerza el teclado numérico y limita el contenido a números.
Button: ejecutar acciones con un toque
El Button es el componente que se utiliza para disparar una acción cuando el usuario lo pulsa: validar un formulario, iniciar un cálculo, abrir otra Activity, llamar a un número, etc. En XML puede definirse así:
<Button
android:id="@+id/my_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/my_button_text" />
El atributo android:text indica el texto que se mostrará en el botón, normalmente referenciado desde un recurso de tipo cadena. Más adelante veremos cómo conectar este botón con código Java tanto con setOnClickListener() como a través del atributo android:onClick en el XML.
Recursos de cadenas (strings.xml): texto centralizado y traducible

Siempre que quieras mostrar texto al usuario es muy recomendable que lo declares como recurso de tipo cadena en res/values/strings.xml. Esto hace la app más mantenible y te permite traducirla fácilmente a otros idiomas sin tocar los layouts.
Un archivo strings.xml sencillo puede tener algo como esto:
<resources>
<string name="app_name">My First App</string>
<string name="edit_message">Introduce un mensaje</string>
<string name="button_send">Enviar</string>
</resources>
Después, desde los layouts XML, usas estos recursos con @string/nombre_cadena. Por ejemplo, el EditText de antes apunta al recurso @string/edit_message y el Button usa @string/button_send. Aunque el ID de un EditText se llame edit_message y también tengas una cadena edit_message, no hay conflicto porque cada uno vive en su propio tipo de recurso (id vs string).
Organizar las vistas: LinearLayout, FrameLayout y RelativeLayout
Las vistas por sí solas no sirven de mucho si no se organizan de algún modo. Ahí entran en juego los layouts (ViewGroup). Cada layout aplica una serie de reglas sobre cómo se colocan sus hijos en pantalla. Los más habituales y didácticos son FrameLayout, LinearLayout y RelativeLayout.
FrameLayout: el contenedor más sencillo
FrameLayout es el layout más básico: apila las vistas una encima de otra, empezando por la primera que declaras en XML. La posición se define principalmente con el atributo layout_gravity de las vistas hijas, que indica en qué parte del contenedor quieres colocarlas (arriba, abajo, centradas, etc.).
Por ejemplo, puedes poner un TextView centrado abajo usando layout_gravity="bottom|center_horizontal". Eso le dice al FrameLayout que esa vista se pegue al borde inferior y se centre horizontalmente. Es un layout muy útil para cosas simples, overlays, o para poner un elemento flotando sobre otros.
LinearLayout: colocar elementos en fila o columna
LinearLayout es un ViewGroup que organiza a sus hijos en una sola fila horizontal o en una sola columna vertical, según el valor de android:orientation. Todas las vistas se muestran en el orden en el que aparecen en el XML.
Un ejemplo de LinearLayout horizontal para un campo de texto y un botón:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<EditText
android:id="@+id/edit_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/edit_message" />
<Button
android:layout_width="wrap_content"
android:text="@string/button_send" />
</LinearLayout>
Las propiedades clave que verás continuamente son android:layout_width y android:layout_height. En la mayoría de los casos usarás los valores:
wrap_content: la vista ocupa el espacio justo para su contenido.match_parent: la vista rellena todo el espacio disponible del padre (antes conocido comofill_parent).
Controlar el espacio con layout_weight
En LinearLayout, además de width y height, tienes un atributo muy potente llamado android:layout_weight. Sirve para repartir el espacio libre entre los hijos como si fueran “porciones” proporcionales.
Por ejemplo, si tienes un EditText y un Button en horizontal, quizá quieras que el campo de texto ocupe todo el espacio sobrante y que el botón se mantenga con su ancho justo. Si le das al EditText un peso de 1 y al botón un peso de 0 (el valor por defecto), el EditText se queda con todo el hueco restante:
<EditText
android:id="@+id/edit_message"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="@string/edit_message" />
Fíjate en que el layout_width del EditText se pone a 0dp. Esto no es un bug: mejora el rendimiento porque el sistema no pierde tiempo calculando un ancho por contenido que después va a ignorar para aplicar el peso.
Si tuvieras más vistas con pesos 1, 2, 3, etc., el LinearLayout reparte el espacio proporcionalmente: una vista con peso 2 ocupa el doble de espacio que otra con peso 1, y así sucesivamente.
RelativeLayout: posicionar vistas unas respecto a otras
RelativeLayout organiza sus hijos en función de reglas de posición relativas: puedes decirle a una vista que esté a la derecha de otra, debajo, alineada al borde izquierdo del padre, centrada verticalmente, etc. Es mucho más flexible que LinearLayout y permite diseños complejos sin necesidad de anidar demasiados layouts.
La idea básica es que cada vista hija tiene un conjunto de reglas que le indican cómo colocarse. Algunas se refieren al padre (el propio RelativeLayout) y otras a vistas hermanas. Para que estas reglas funcionen es imprescindible que cada vista hija tenga su android:id bien definido.
Imagina un diseño con un EditText y un Button, donde el botón debe quedar a la derecha del campo de texto. Podrías definirlo así en XML:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/editText01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@id/button01" />
<Button
android:id="@+id/button01"
android:layout_width="wrap_content"
android:layout_alignParentRight="true" />
</RelativeLayout>
Aquí el EditText se alinea al borde izquierdo del layout y se coloca a la izquierda del Button. El Button se alinea al borde derecho. Esta combinación de reglas genera exactamente el efecto de “campo de texto a la izquierda, botón a la derecha” sin pelearte con márgenes fijos.
RelativeLayout tiene muchas reglas útiles:
- Alineación al padre:
layout_alignParentTop,layout_alignParentBottom,layout_alignParentLeft,layout_alignParentRight. - Posición relativa a otra vista:
layout_above,layout_below,layout_toLeftOf,layout_toRightOf. - Centrado:
layout_centerHorizontal,layout_centerVertical,layout_centerInParent.
Con estas reglas puedes hacer pantallas muy ricas: textos centrados, bloques a izquierda y derecha, barras en el fondo de la pantalla, etc., sin necesidad de estructuras enrevesadas de layouts anidados que penalizan el rendimiento.
Crear y configurar layouts por código (cuando no hay XML)
Aunque en la mayoría de casos diseñarás las interfaces en XML (porque es más claro y mantenible), también tienes la opción de construir layouts y vistas completamente desde Java. Esto es útil para casos muy dinámicos o cuando el diseño depende en gran medida de datos de tiempo de ejecución.
En el caso de RelativeLayout, usarías la clase RelativeLayout como padre y RelativeLayout.LayoutParams para los parámetros de las vistas hijas. Además, seguirás usando los parámetros genéricos de ViewGroup.LayoutParams (como width y height) y de ViewGroup.MarginLayoutParams (márgenes).
El flujo general es:
- Crear las vistas hijas (TextView, Button, EditText, etc.).
- Crear unos LayoutParams específicos para RelativeLayout.
- Añadir reglas a esos LayoutParams (por ejemplo, centrar, alinear, etc.).
- Crear el RelativeLayout padre, asignarle sus propios LayoutParams.
- Ir llamando a
addView()para insertar las vistas hijas con sus LayoutParams. - Finalmente llamar a
setContentView(relativeLayout)desde la Activity.
Esto funciona muy bien, pero a poco que se complique la pantalla el código crece muchísimo, así que suele ser mejor reservar este enfoque para casos especiales. Para todo lo demás, XML al rescate.
Ejemplo práctico: sumar dos números usando EditText, Button y TextView
Vamos ahora con un caso completo y muy habitual en primeros proyectos: una pantalla con dos campos numéricos, un botón para hacer la suma y un TextView para mostrar el resultado. Con esto verás la conexión real entre XML y código Java, y cómo se captura el evento de pulsar el botón.
Diseñar la interfaz en XML
Partimos de un proyecto nuevo (por ejemplo, llamado Proyecto002) creado con Android Studio. La plantilla añade de serie un TextView en el activity_main.xml; lo primero que hacemos es borrar ese TextView y diseñar nuestra interfaz desde cero, normalmente usando un ConstraintLayout como contenedor raíz.
Desde la paleta, pestaña “Text”, arrastramos un componente de tipo “Number” (que internamente es un EditText numérico) y lo dejamos en la parte superior izquierda del diseño. Usamos el botón “Infer Constraints” o colocamos manualmente las constraints para fijarlo dentro del ConstraintLayout.
En la ventana de propiedades, modificamos:
- id: le ponemos, por ejemplo,
et1. - hint: escribimos “Ingrese el primer valor”.
Repetimos la operación para un segundo EditText de tipo Number, con:
- id:
et2. - hint: “Ingrese el segundo valor”.
El resultado es una pantalla con dos campos de texto numéricos, cada uno mostrando un mensaje de ayuda mientras están vacíos, lo que hace la interfaz mucho más intuitiva para el usuario.
Ahora, desde la pestaña “Buttons”, arrastramos un Button y lo colocamos debajo de los EditText. Configuramos:
- id: dejamos el valor por defecto (por ejemplo,
buttonsi así lo genera Android Studio). - text: “Sumar”.
Por último, añadimos un TextView que mostrará el resultado de la suma. Le asignamos:
- id:
tv1. - text: “Resultado”.
Con esto ya tenemos la interfaz completa: dos EditText para introducir números, un Button para lanzar la suma y un TextView para el resultado. Si ejecutáramos la app ahora, veríamos la pantalla, podríamos escribir en los EditText, pero al pulsar el botón no pasaría nada porque todavía no hay lógica asociada.
Preparar la Activity y enlazar vistas con findViewById
Abrimos la clase MainActivity, que en un proyecto nuevo tendrá algo de este estilo:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
La clase MainActivity hereda de AppCompatActivity, que es la representación de una ventana de Android. Lo mínimo es sobrescribir onCreate() y llamar a setContentView() para indicar qué layout va con esta Activity.
Para trabajar con los EditText y el TextView, definimos variables miembro en la Activity:
private EditText et1;
private EditText et2;
private TextView tv1;
Android Studio te marcará en rojo las clases hasta que las importes. Lo más cómodo es usar la combinación de teclas habitual (Alt+Enter sobre el nombre de la clase) para que añada automáticamente:
import android.widget.EditText;
import android.widget.TextView;
Después, en onCreate(), enlazamos estas variables con las vistas de XML mediante findViewById():
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et1 = findViewById(R.id.et1);
et2 = findViewById(R.id.et2);
tv1 = findViewById(R.id.tv1);
}
Las constantes R.id.et1, R.id.et2 y R.id.tv1 se generan automáticamente a partir de los IDs definidos en el XML. La famosa clase R es el puente entre recursos y código: por cada layout, id, string, etc., genera una referencia constante que usas en Java/Kotlin.
Capturar el clic del botón: método público o setOnClickListener
Para que al pulsar el botón se ejecute código, tienes dos enfoques muy usados:
- Declarar un método público en la Activity y enlazarlo desde el XML con
android:onClick. - Buscar el botón con
findViewById()y asignar unsetOnClickListener().
En el ejemplo que estamos siguiendo usamos el primer enfoque, muy cómodo para proyectos sencillos. Definimos un método público en la Activity que reciba un parámetro de tipo View:
public void sumar(View view) {
}
Importamos android.view.View si hace falta. Después, en el editor de diseño (o en el XML a mano) vamos al botón y establecemos la propiedad onClick con el valor sumar. Eso le indica a Android que, cuando se pulse ese botón concreto, debe llamar al método sumar() de la Activity.
Lógica para sumar los números y mostrar el resultado
Ahora implementamos el contenido del método sumar(). El flujo es:
- Leer el texto de
et1yet2. - Convertir esas cadenas a enteros.
- Sumarlos.
- Convertir el resultado a String.
- Actualizar el TextView
tv1con el resultado.
En código quedaría así:
public void sumar(View view) {
String valor1 = et1.getText().toString();
String valor2 = et2.getText().toString();
int nro1 = Integer.parseInt(valor1);
int nro2 = Integer.parseInt(valor2);
int suma = nro1 + nro2;
String resu = String.valueOf(suma);
tv1.setText(resu);
}
Los dos primeros pasos obtienen el contenido de los EditText. Ten en cuenta que getText() devuelve un objeto Editable, así que se pasa a String con toString(). Después parseamos a int con Integer.parseInt(), hacemos la suma y convertimos de nuevo a String con String.valueOf(). Por último, setText() cambia el texto del TextView y muestra el resultado en pantalla.
La clase completa queda algo así:
public class MainActivity extends AppCompatActivity {
private EditText et1;
private EditText et2;
private TextView tv1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et1 = findViewById(R.id.et1);
et2 = findViewById(R.id.et2);
tv1 = findViewById(R.id.tv1);
}
public void sumar(View view) {
String valor1 = et1.getText().toString();
String valor2 = et2.getText().toString();
int nro1 = Integer.parseInt(valor1);
int nro2 = Integer.parseInt(valor2);
int suma = nro1 + nro2;
String resu = String.valueOf(suma);
tv1.setText(resu);
}
}
Al ejecutar la app, verás que los EditText muestran los mensajes “Ingrese el primer valor” e “Ingrese el segundo valor”; escribes dos enteros, pulsas el botón “Sumar” y el TextView cambia su texto por la suma. Es un ejemplo perfecto para entender cómo se comunican el XML, los IDs, el código Java y los eventos de usuario.
Más vistas y layouts: Email, Phone, jerarquías y propiedades clave
Además de TextView, EditText y Button, Android incluye otras vistas como ImageView para imágenes, campos específicos tipo E-mail o Phone (basados en EditText, pero con teclado y validaciones adaptadas), y un amplio conjunto de layouts.
En un formulario típico podrías tener un LinearLayout vertical con varios EditText (nombre, email, teléfono) y un botón final de envío. Cada elemento se declara uno debajo de otro y el propio LinearLayout se encarga de colocarlos como filas. Si quisieras ponerlos horizontalmente (por ejemplo, email y teléfono en la misma línea), cambiarías la orientación a horizontal y jugarías con los pesos y anchos para que se reparta el espacio.
Otros atributos muy recurrentes cuando trabajas con vistas son:
layout_width: ancho de la vista. Valores más comunes:wrap_contentymatch_parent.layout_height: alto de la vista. Mismos valores típicos que width.layout_weight: reparto proporcional de espacio en LinearLayout.gravitydel padre: indica cómo se colocan los hijos dentro del contenedor (por ejemplo,center,center_horizontal,bottom…).layout_gravitydel hijo: especifica cómo se posiciona esa vista dentro de su padre en layouts que lo soportan (como FrameLayout).
Usar bien estas propiedades es lo que marca la diferencia entre una interfaz que “medio se ve bien” y una interfaz adaptable, limpia y fácil de mantener, incluso cuando rotas el dispositivo o cambias de tamaño de pantalla.
Cuando dominas los distintos tipos de vistas (TextView, EditText, Button, ImageView, etc.) y entiendes cómo se relacionan con ViewGroup como FrameLayout, LinearLayout o RelativeLayout, puedes construir pantallas muy potentes con muy poco código extra. A partir de ahí, solo es cuestión de practicar: jugar con pesos, centrados, alineaciones relativas y capturar eventos para que cada interacción del usuario tenga una respuesta clara en tu aplicación. Comparte la guía para que más usuarios conzocan del tema.


