Las actividades son un componente fundamental en el desarrollo de Android. Una actividad encapsula una pantalla con la que el usuario interactúa. Las actividades suelen contener componentes con los que el usuario debe interactuar. Estos pueden ser botones, listas, textos de edición, etc. Sin embargo, la actividad tiene su propio ciclo de vida y puedes escuchar los eventos emitidos por la actividad a través de los métodos del ciclo de vida.

En este tutorial aprenderemos estos métodos del ciclo de vida de forma práctica escribiendo código que haga algo cuando se levante un evento de este tipo.

(a). Crear una aplicación que liste los métodos del ciclo de vida de la actividad en Kotlin

En este ejemplo aprenderás la interacción básica con estos métodos. Mostramos un simple mensaje de brindis cuando se levanta un evento de este tipo.

Usamos android studio y kotlin

Paso 1: Dependencias

No se necesitan dependencias para este proyecto.

Paso 2: Código Kotlin

Comienza creando un archivo llamado MaiActivity.kt.

MainActivity.kt

Luego añade las importaciones:

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
import java.lang.StringBuilder

Luego extiende la AppCompatActivity:

class MainActivity : AppCompatActivity() {
    //

El primer método del ciclo de vida que sobrescribimos es el onCreate(). Este método se ejecuta cuando la actividad se crea por primera vez. Aquí inflaremos nuestro diseño xml. Luego añadiremos un texto a nuestro textbuilder. Luego mostraremos el texto en un textview.

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        sb.append("\n onCreate Called")
        tv.text = sb.toString()
        Log.d("ACTIVITY_LIFECYCLE", "onCreate Called")
    }

Luego anulamos nuestro onStart(). Esto se levanta cuando la actividad se inicia y se hace visible para su uso:


    override fun onStart() {
        super.onStart()
        sb.append("\n onStart Called")
        tv.text = sb.toString()
        Log.d("ACTIVITY_LIFECYCLE", "onStart Called")
    }

Y así sucesivamente.

Aquí está el código completo:

package info.camposha.activitylifecycle

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
import java.lang.StringBuilder

class MainActivity : AppCompatActivity() {
    val sb: StringBuilder = StringBuilder()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        sb.append("\n onCreate Called")
        tv.text = sb.toString()
        Log.d("ACTIVITY_LIFECYCLE", "onCreate Called")
    }

    override fun onStart() {
        super.onStart()
        sb.append("\n onStart Called")
        tv.text = sb.toString()
        Log.d("ACTIVITY_LIFECYCLE", "onStart Called")
    }

    override fun onResume() {
        super.onResume()
        sb.append("\n onResume Called")
        tv.text = sb.toString()
        Log.d("ACTIVITY_LIFECYCLE", "onResume Called")
    }

    override fun onPause() {
        super.onPause()
        sb.append("\n onPause Called")
        tv.text = sb.toString()
        Log.d("ACTIVITY_LIFECYCLE", "onPause Called")
    }

    override fun onStop() {
        super.onStop()
        sb.append("\n onStop Called")
        tv.text = sb.toString()
        Log.d("ACTIVITY_LIFECYCLE", "onStop Called")
    }

    override fun onDestroy() {
        super.onDestroy()
        sb.append("\n onDestroy Called")
        tv.text = sb.toString()
        Log.d("ACTIVITY_LIFECYCLE", "onDestroy Called")
    }
}

Paso 3: Diseños

**Actividad_principal.xml

Lo principal de nuestro layout de la actividad principal es que tendremos un textview que irá mostrando los métodos del ciclo de vida a medida que se vayan levantando:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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=".MainActivity">

    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text=""
        android:textAppearance="@style/TextAppearance.AppCompat.Medium"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Paso 4: Ejecutar

Ejecutar el proyecto.

Cambio de configuración de la pantalla

En esta pieza vemos las soluciones de android relacionadas con los cambios de configuración en el dispositivo android.

Aquí hay una simple nota sobre el manejo de los cambios de configuración de acuerdo con la documentación oficial de android:

Algunas configuraciones del dispositivo pueden cambiar durante el tiempo de ejecución (como la orientación de la pantalla, la disponibilidad del teclado y cuando el usuario activa el modo multiventana). Cuando se produce un cambio de este tipo, Android reinicia la Activity en ejecución (se llama a onDestroy(), seguido de onCreate(). El comportamiento de reinicio está diseñado para ayudar a su aplicación a adaptarse a las nuevas configuraciones mediante la recarga automática de su aplicación con recursos alternativos que coinciden con la nueva configuración del dispositivo.

Para manejar adecuadamente un reinicio, es importante que tu actividad restaure su estado anterior. Puedes utilizar una combinación de objetos onSaveInstanceState(), ViewModel y almacenamiento persistente para guardar y restaurar el estado de la interfaz de usuario de tu actividad a través de los cambios de configuración. Lee más sobre esto aquí.

¿Cómo se escuchan los cambios de configuración en android?

Paso 1 – Especificar la propiedad configChanges en el manifiesto de android

Así:

<activity android:name=".MyActivity"
          android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
          android:label="@string/app_name">

El código declara una actividad que maneja tanto los cambios de orientación de la pantalla como el cambio de disponibilidad del teclado.

  • El valor "orientation" evita los reinicios cuando la orientación de la pantalla cambia.
  • El valor "screenSize" también evita los reinicios cuando la orientación cambia, pero sólo para Android 3.2 (nivel de API 13) y superior.
  • El valor "screenLayout" es necesario para detectar los cambios que pueden provocar dispositivos como los teléfonos plegables y los Chromebooks convertibles.
  • El valor "keyboardHidden" evita los reinicios cuando cambia la disponibilidad del teclado.

Paso 2: Anular el método onConfigurationChanged

Así:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    int newOrientation = newConfig.orientation;

    if (newOrientation == Configuration.ORIENTATION_LANDSCAPE) {
      // show("Landscape");
    } else if (newOrientation == Configuration.ORIENTATION_PORTRAIT){
    // show("Portrait");
    }
}

O puedes utilizar una sentencia switch:

int orientation=newConfig.orientation;
switch(orientation) {
    case Configuration.ORIENTATION_LANDSCAPE:
        //to do something
        break;
    case Configuration.ORIENTATION_PORTRAIT:
        //to do something
        break;
}

En Kotlin:

override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)

    // Checks the orientation of the screen
    if (newConfig.orientation === Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show()
    } else if (newConfig.orientation === Configuration.ORIENTATION_PORTRAIT) {
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show()
    }
}

Ten en cuenta que después de antes de escribir tu código de implementación necesitas añadir super.onConfigurationChanged(newConfig); o de lo contrario se puede lanzar una excepción.

Observaciones

El onConfigurationCalled() puede no ser llamado si

1.Establece el diseño como apaisado en el XML

    android:screenOrientation="landscape"

2. Invoca setRequestedOrientation manualmente

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

3. Tienes ambos android:screenOrientation y android:configChanges especificados.

Ejemplo – Cómo manejar los cambios de orientación de la pantalla

Vamos a crear un ejemplo simple que observará los cambios de configuración en una actividad androide y mostrará un mensaje de tostado en función de si la pantalla está girada en vertical u horizontal.

Paso 1- Crear Layout

Añade el siguiente código en tu layout xml:

<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</RelativeLayout>

Paso 2: MainActivity.java

Luego agregue el siguiente código en su actividad principal:

package com.example.screenorientation;

import android.os.Bundle;
import android.app.Activity;
import android.content.res.Configuration;
import android.view.Menu;
import android.widget.Toast;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        onConfigurationChanged(new Configuration());
    }
@Override
public void onConfigurationChanged(Configuration newConfig) {
    // TODO Auto-generated method stub
    super.onConfigurationChanged(newConfig);

    if(getResources().getConfiguration().orientation==Configuration.ORIENTATION_PORTRAIT)
    {
        Toast.makeText(getApplicationContext(), "portrait", Toast.LENGTH_SHORT).show();
        System.out.println("portrait");
    }
    else if (getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE) {
         Toast.makeText(getApplicationContext(), "landscape", Toast.LENGTH_SHORT).show();
            System.out.println("landscape");
    }
    else
    {
         Toast.makeText(getApplicationContext(), "none", Toast.LENGTH_SHORT).show();
            System.out.println("none");
    }
}
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

Eso es todo.