Diferencia entre revisiones de «Chronometer. Cliclo de vida I (finish())»
Ir a la navegación
Ir a la búsqueda
(Página creada con «==Introdución== *Un control '''Chronometer''' implementa en Android un cronómetro simple. *Iníciase con '''start()''' *Párase con stop(). Pero ... el segue contando po...») |
|||
| (No se muestran 5 ediciones intermedias de otro usuario) | |||
| Línea 1: | Línea 1: | ||
==Introdución== | ==Introdución== | ||
| + | |||
*Un control '''Chronometer''' implementa en Android un cronómetro simple. | *Un control '''Chronometer''' implementa en Android un cronómetro simple. | ||
| − | *Iníciase | + | :*Iníciase có [https://developer.android.com/reference/android/widget/Chronometer.html#start() método start()]. |
| + | :*Párase có [https://developer.android.com/reference/android/widget/Chronometer.html#stop() método stop()]. Pero ... el segue contando por detrás. Isto é, se se executa de novo start() sen parámetros porá o cronómetro no mesmo tempo que se non se parase. | ||
| − | |||
*Cando se chama a '''start()''', o control colle o tempo que leva acceso o móbil ('''elapsedRealtime()''') como tempo base e vai contando dende aí. | *Cando se chama a '''start()''', o control colle o tempo que leva acceso o móbil ('''elapsedRealtime()''') como tempo base e vai contando dende aí. | ||
| + | : Se non se lle dá un tempo base el colle o tempo no cal se chama a '''start()'''. | ||
| − | |||
| − | |||
| − | |||
| − | |||
| + | *Para establecer un tempo base úsase o [https://developer.android.com/reference/android/widget/Chronometer.html#setBase(long) méotdo setBase()]. | ||
| − | *Por defecto amosa o tempo en formato "MM:SS". Pódese usar | + | *Por defecto amosa o tempo en formato "MM:SS". Pódese usar o [https://developer.android.com/reference/android/widget/Chronometer.html#setFormat(java.lang.String) método setFormat(String)] para cambiar o formato. |
*A clase '''Chronometer''' herda directamente da clase '''View'''. | *A clase '''Chronometer''' herda directamente da clase '''View'''. | ||
| − | + | *Para establecer os valores de tempos base apoiámonos na [https://developer.android.com/reference/android/os/SystemClock clase SystemClock]. | |
| − | |||
| − | *Para establecer os valores de tempos base apoiámonos na clase | ||
| Línea 28: | Línea 25: | ||
==Caso práctico== | ==Caso práctico== | ||
| − | * | + | |
| − | * | + | * Partimos que xa temos creado o proxecto inicial como [http://wiki.cifprodolfoucha.es/index.php?title=PDM_Creando_proxecto_base xa indicamos anteriormente]. |
| + | : Se non o temos creado antes, crea un paquete de nome '''UI''' como un subpaquete do teu paquete principal. | ||
| + | : Dentro do paquete UI, crearemos un novo paquete de nome: '''Chonometers'''. | ||
| + | |||
| + | |||
| + | <br /> | ||
| + | * Dentro do paquete '''Chonometers''' crear unha nova 'Empty Activity' de nome: '''UD02_01_Chonometer''' de tipo Launcher e sen compatibilidade. | ||
| + | : Modifica o arquivo '''AndroidManifiest.xml''' e engade unha label á activity como [http://wiki.cifprodolfoucha.es/index.php?title=PDM_Creando_proxecto_base xa vimos na creación do proxecto base]. | ||
| + | |||
| + | |||
| + | <br /> | ||
<gallery caption="Autodestrucción" widths="350" heights="300px" perrow="2"> | <gallery caption="Autodestrucción" widths="350" heights="300px" perrow="2"> | ||
| − | Image: | + | Image:PDM_chrono_1.jpg| Ao iniciar a aplicación o crono está parado. Iniciámolo. |
| − | Image: | + | Image:PDM_chrono_2.jpg| O crono está en funcionamento e se non se para autodestruirase a aplicación en X seg. O valor de partida para a autodestrucción establécese nunha variable no código. |
| − | Image: | + | Image:PDM_chrono_3.jpg| Parouse o crono. Se se preme en Start, é como comezar de novo. |
</gallery> | </gallery> | ||
| − | + | <br /> | |
===XML do Layout=== | ===XML do Layout=== | ||
*Observar como se crea o control Chronometer e os métodos aos que chaman os botóns. | *Observar como se crea o control Chronometer e os métodos aos que chaman os botóns. | ||
| − | <syntaxhighlight lang="xml" line enclose="div" highlight="13-18,23 | + | <syntaxhighlight lang="xml" line enclose="div" highlight="13-18,23" > |
<?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||
| Línea 50: | Línea 57: | ||
<TextView | <TextView | ||
| − | android:id="@+id/ | + | android:id="@+id/tvAutodestr_UD02_01_Chonometer" |
android:layout_width="wrap_content" | android:layout_width="wrap_content" | ||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||
| Línea 56: | Línea 63: | ||
<Chronometer | <Chronometer | ||
| − | android:id="@+id/ | + | android:id="@+id/chrCronometro_UD02_01_Chonometer" |
android:layout_width="wrap_content" | android:layout_width="wrap_content" | ||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||
| Línea 69: | Línea 76: | ||
<Button | <Button | ||
| − | android:id="@+id/ | + | android:id="@+id/btStart_UD02_01_Chonometer" |
android:layout_width="wrap_content" | android:layout_width="wrap_content" | ||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||
| − | |||
android:text="Start" /> | android:text="Start" /> | ||
<Button | <Button | ||
| − | android:id="@+id/ | + | android:id="@+id/btStop_UD02_01_Chonometer" |
android:layout_width="wrap_content" | android:layout_width="wrap_content" | ||
android:layout_height="wrap_content" | android:layout_height="wrap_content" | ||
| − | |||
android:text="Stop" /> | android:text="Stop" /> | ||
</LinearLayout> | </LinearLayout> | ||
| Línea 86: | Línea 91: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| + | |||
| + | <br /> | ||
===Código Java=== | ===Código Java=== | ||
| − | <syntaxhighlight lang="java" line enclose="div" highlight=" | + | <syntaxhighlight lang="java" line enclose="div" highlight="21-38,40-49,51-57,65" > |
| − | package | + | package es.cursoandroid.cifprodolfoucha.aprendiendo.UI.Chronometers; |
import android.app.Activity; | import android.app.Activity; | ||
import android.os.Bundle; | import android.os.Bundle; | ||
import android.os.SystemClock; | import android.os.SystemClock; | ||
| − | |||
import android.view.View; | import android.view.View; | ||
| + | import android.widget.Button; | ||
import android.widget.Chronometer; | import android.widget.Chronometer; | ||
| − | |||
import android.widget.TextView; | import android.widget.TextView; | ||
| − | public class | + | import es.cursoandroid.cifprodolfoucha.aprendiendo.R; |
| − | + | ||
| − | + | public class UD02_01_Chronometer extends Activity { | |
| − | + | ||
| + | private int tempoAutodestrucion; // Non podemos declarala final xa que se modifica o seu valor. Ao ter unha referencia a ela dentro da clase anónima OnChronometerTickListener, temos que declaralo a nivel de clase | ||
| + | private Chronometer crono; | ||
| + | |||
| + | private void xestionarEventos(){ | ||
| + | final TextView tvAutodestrucion; | ||
| + | |||
| + | // Eventos do crono | ||
| + | crono = (Chronometer) findViewById(R.id.chrCronometro_UD02_01_Chonometer); | ||
| + | tvAutodestrucion = (TextView) findViewById(R.id.tvAutodestr_UD02_01_Chonometer); // O poñemos aquí xa que o método onChronometerTick execútase moitas veces | ||
| + | crono.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() { | ||
| + | @Override | ||
| + | public void onChronometerTick(Chronometer chronometer) { | ||
| + | // TODO Auto-generated method stub | ||
| − | + | long tempoPasado = SystemClock.elapsedRealtime() | |
| − | + | - chronometer.getBase(); | |
| − | + | int tempoSeg = (int) tempoPasado / 1000; | |
| − | + | if (tempoSeg == tempoAutodestrucion) | |
| − | + | finish(); | |
| − | |||
| − | + | tvAutodestrucion.setText("Autodestrucción en: " | |
| − | + | + (tempoAutodestrucion - tempoSeg) + " seg"); | |
| − | + | } | |
| − | + | }); | |
| − | + | // Eventos botón start | |
| − | + | Button btStart = findViewById(R.id.btStart_UD02_01_Chonometer); | |
| − | + | btStart.setOnClickListener(new View.OnClickListener() { | |
| − | + | @Override | |
| − | + | public void onClick(View v) { | |
| + | tempoAutodestrucion = 20; | ||
| + | crono.setBase(SystemClock.elapsedRealtime()); | ||
| + | crono.start(); | ||
| + | } | ||
| + | }); | ||
| − | + | //Eventos botón stop (non temos por que declarar unha variable) | |
| − | + | ((Button)findViewById(R.id.btStop_UD02_01_Chonometer)).setOnClickListener(new View.OnClickListener() { | |
| − | + | @Override | |
| − | + | public void onClick(View v) { | |
| − | + | crono.stop(); | |
| + | } | ||
| + | }); | ||
| − | + | } | |
| − | + | @Override | |
| − | + | protected void onCreate(Bundle savedInstanceState) { | |
| − | + | super.onCreate(savedInstanceState); | |
| − | + | setContentView(R.layout.activity_ud02_01__chronometer); | |
| − | + | xestionarEventos(); | |
| − | + | } | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| − | *'''Liña | + | |
| − | *'''Liña | + | * Liñas 40-49: Xestionamos o evento de Click sobre o botón start: |
| − | + | :*'''Liña 45''': Definimos o tempo para a autodestrucción da Activity. Cando se vexan os menús, veremos que este valor podería ser configurado polo usuario que usa a aplicación, como unha opción da mesma. | |
| − | *'''Liña | + | :*'''Liña 46''': establécese o tempo base a partir do cal o cronómetro comeza a contar. SystemClock.elapsedRealtime(): devolve o tempo, en milisegundos, que leva aceso o móbil |
| − | *'''Liña | + | :*'''Liña 47''': o cronómetro comeza a contar, non dende cero, senón dende o tempo tomado como base (o tempo que leva acceso o móbil). |
| − | *'''Liña 24''': establécese o Listener do cronómetro. Este método vai ser chamado cada vez que o cronómetro cambia de valor. | + | |
| − | *'''Liñas 29 e 30''': O tempo que pasou dende que se iniciou o cronómetro é a diferencia entre o tempo que leva acceso o dispositivo e o tempo no cal se iniciou o cronómetro. | + | * Liñas 51-57: Xestionamos o evento de Click sobre o botón stop: |
| − | *'''Liña 31''': Tempo en segundos. | + | :*'''Liña 55''': párase o cronómetro. |
| − | *'''Liña 33''': Se chegamos ao tempo para autodestrucción hai que matar a Activity. Sería o mesmo que se prememos o botón da botonera "Retroceso ou Back". | + | |
| + | * Liñas 21-38: Xestionamos o listener no cronómetro que se chama cada vez que hai un cambio no seu valor: | ||
| + | :*'''Liña 24''': establécese o Listener do cronómetro. Este método vai ser chamado cada vez que o cronómetro cambia de valor. | ||
| + | :*'''Liñas 29 e 30''': O tempo que pasou dende que se iniciou o cronómetro é a diferencia entre o tempo que leva acceso o dispositivo e o tempo no cal se iniciou o cronómetro. | ||
| + | :*'''Liña 31''': Tempo en segundos. | ||
| + | :*'''Liña 33''': Se chegamos ao tempo para autodestrucción hai que matar a Activity. Sería o mesmo que se prememos o botón da botonera "Retroceso ou Back". | ||
==Ciclo de vida dunha actividade== | ==Ciclo de vida dunha actividade== | ||
| Línea 168: | Línea 191: | ||
*Para iso úsase o método '''finish()'''. | *Para iso úsase o método '''finish()'''. | ||
*Ver liña 33 do código. | *Ver liña 33 do código. | ||
| + | |||
| + | |||
| + | |||
| + | * Como exercicio, podedes ir lendo a sección [http://wiki.cifprodolfoucha.es/index.php?title=Ciclo_de_vida_dunha_aplicaci%C3%B3n#Recrear_unha_actividade:_gardar_e_recuperar_o_seu_estado Recrear unha actividade: gardar e recuperar o seu estado] e facer que cando rotades o dispositivo o Cronómetro continúe no mesmo punto onde estaba. | ||
| + | |||
| Línea 173: | Línea 201: | ||
| + | <br /> | ||
| + | '''[https://wiki.cifprodolfoucha.es/index.php?title=Programaci%C3%B3n_de_dispositivos_m%C3%B3biles#UNIDADE_2:_A_interface_de_usuario. Enlace a la página principal de la UD2]''' | ||
| + | <br /> | ||
| + | <br /> | ||
| + | '''[https://wiki.cifprodolfoucha.es/index.php?title=Programación_de_dispositivos_móbiles Enlace a la página principal del curso]''' | ||
| + | <br /> | ||
<br> -- [[Usuario:angelfg|Ángel D. Fernández González]] e [[Usuario:Carrion|Carlos Carrión Álvarez]] -- (2015). | <br> -- [[Usuario:angelfg|Ángel D. Fernández González]] e [[Usuario:Carrion|Carlos Carrión Álvarez]] -- (2015). | ||
Revisión actual del 12:57 21 nov 2020
Sumario
Introdución
- Un control Chronometer implementa en Android un cronómetro simple.
- Iníciase có método start().
- Párase có método stop(). Pero ... el segue contando por detrás. Isto é, se se executa de novo start() sen parámetros porá o cronómetro no mesmo tempo que se non se parase.
- Cando se chama a start(), o control colle o tempo que leva acceso o móbil (elapsedRealtime()) como tempo base e vai contando dende aí.
- Se non se lle dá un tempo base el colle o tempo no cal se chama a start().
- Para establecer un tempo base úsase o méotdo setBase().
- Por defecto amosa o tempo en formato "MM:SS". Pódese usar o método setFormat(String) para cambiar o formato.
- A clase Chronometer herda directamente da clase View.
- Para establecer os valores de tempos base apoiámonos na clase SystemClock.
- Referencias:
- Clase Chronometer: http://developer.android.com/reference/android/widget/Chronometer.html
- Clase SystemClock: http://developer.android.com/reference/android/os/SystemClock.html
Caso práctico
- Partimos que xa temos creado o proxecto inicial como xa indicamos anteriormente.
- Se non o temos creado antes, crea un paquete de nome UI como un subpaquete do teu paquete principal.
- Dentro do paquete UI, crearemos un novo paquete de nome: Chonometers.
- Dentro do paquete Chonometers crear unha nova 'Empty Activity' de nome: UD02_01_Chonometer de tipo Launcher e sen compatibilidade.
- Modifica o arquivo AndroidManifiest.xml e engade unha label á activity como xa vimos na creación do proxecto base.
- Autodestrucción
XML do Layout
- Observar como se crea o control Chronometer e os métodos aos que chaman os botóns.
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 android:orientation="vertical" >
6
7 <TextView
8 android:id="@+id/tvAutodestr_UD02_01_Chonometer"
9 android:layout_width="wrap_content"
10 android:layout_height="wrap_content"
11 android:text="Autodestrucción en: ?? seg" />
12
13 <Chronometer
14 android:id="@+id/chrCronometro_UD02_01_Chonometer"
15 android:layout_width="wrap_content"
16 android:layout_height="wrap_content"
17 android:layout_gravity="center_horizontal"
18 android:textSize="20sp" />
19
20 <LinearLayout
21 android:layout_width="match_parent"
22 android:layout_height="match_parent"
23 android:gravity="center_horizontal"
24 android:orientation="horizontal" >
25
26 <Button
27 android:id="@+id/btStart_UD02_01_Chonometer"
28 android:layout_width="wrap_content"
29 android:layout_height="wrap_content"
30 android:text="Start" />
31
32 <Button
33 android:id="@+id/btStop_UD02_01_Chonometer"
34 android:layout_width="wrap_content"
35 android:layout_height="wrap_content"
36 android:text="Stop" />
37 </LinearLayout>
38
39 </LinearLayout>
Código Java
1 package es.cursoandroid.cifprodolfoucha.aprendiendo.UI.Chronometers;
2
3 import android.app.Activity;
4 import android.os.Bundle;
5 import android.os.SystemClock;
6 import android.view.View;
7 import android.widget.Button;
8 import android.widget.Chronometer;
9 import android.widget.TextView;
10
11 import es.cursoandroid.cifprodolfoucha.aprendiendo.R;
12
13 public class UD02_01_Chronometer extends Activity {
14
15 private int tempoAutodestrucion; // Non podemos declarala final xa que se modifica o seu valor. Ao ter unha referencia a ela dentro da clase anónima OnChronometerTickListener, temos que declaralo a nivel de clase
16 private Chronometer crono;
17
18 private void xestionarEventos(){
19 final TextView tvAutodestrucion;
20
21 // Eventos do crono
22 crono = (Chronometer) findViewById(R.id.chrCronometro_UD02_01_Chonometer);
23 tvAutodestrucion = (TextView) findViewById(R.id.tvAutodestr_UD02_01_Chonometer); // O poñemos aquí xa que o método onChronometerTick execútase moitas veces
24 crono.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
25 @Override
26 public void onChronometerTick(Chronometer chronometer) {
27 // TODO Auto-generated method stub
28
29 long tempoPasado = SystemClock.elapsedRealtime()
30 - chronometer.getBase();
31 int tempoSeg = (int) tempoPasado / 1000;
32 if (tempoSeg == tempoAutodestrucion)
33 finish();
34
35 tvAutodestrucion.setText("Autodestrucción en: "
36 + (tempoAutodestrucion - tempoSeg) + " seg");
37 }
38 });
39
40 // Eventos botón start
41 Button btStart = findViewById(R.id.btStart_UD02_01_Chonometer);
42 btStart.setOnClickListener(new View.OnClickListener() {
43 @Override
44 public void onClick(View v) {
45 tempoAutodestrucion = 20;
46 crono.setBase(SystemClock.elapsedRealtime());
47 crono.start();
48 }
49 });
50
51 //Eventos botón stop (non temos por que declarar unha variable)
52 ((Button)findViewById(R.id.btStop_UD02_01_Chonometer)).setOnClickListener(new View.OnClickListener() {
53 @Override
54 public void onClick(View v) {
55 crono.stop();
56 }
57 });
58
59 }
60 @Override
61 protected void onCreate(Bundle savedInstanceState) {
62 super.onCreate(savedInstanceState);
63 setContentView(R.layout.activity_ud02_01__chronometer);
64
65 xestionarEventos();
66 }
67
68
69 }
- Liñas 40-49: Xestionamos o evento de Click sobre o botón start:
- Liña 45: Definimos o tempo para a autodestrucción da Activity. Cando se vexan os menús, veremos que este valor podería ser configurado polo usuario que usa a aplicación, como unha opción da mesma.
- Liña 46: establécese o tempo base a partir do cal o cronómetro comeza a contar. SystemClock.elapsedRealtime(): devolve o tempo, en milisegundos, que leva aceso o móbil
- Liña 47: o cronómetro comeza a contar, non dende cero, senón dende o tempo tomado como base (o tempo que leva acceso o móbil).
- Liñas 51-57: Xestionamos o evento de Click sobre o botón stop:
- Liña 55: párase o cronómetro.
- Liñas 21-38: Xestionamos o listener no cronómetro que se chama cada vez que hai un cambio no seu valor:
- Liña 24: establécese o Listener do cronómetro. Este método vai ser chamado cada vez que o cronómetro cambia de valor.
- Liñas 29 e 30: O tempo que pasou dende que se iniciou o cronómetro é a diferencia entre o tempo que leva acceso o dispositivo e o tempo no cal se iniciou o cronómetro.
- Liña 31: Tempo en segundos.
- Liña 33: Se chegamos ao tempo para autodestrucción hai que matar a Activity. Sería o mesmo que se prememos o botón da botonera "Retroceso ou Back".
Ciclo de vida dunha actividade
- Afondarase máis adiante sobre o ciclo de vida dunha actividade.
- Unha actividade desde que se lanza pasa por moitos estados.
- Cando unha actividade non está en primeira liña da pantalla non está destruída senón que está en estado de Stop (Oculta) esperando na pila a ser chamada, ou se está moi abaixo na pila e se precisan os seus recursos entón o sistema pode destruíla.
- No noso exemplo a actividade destrúese explicitamente se o cronómetro chega a un tempo determinado
- Para iso úsase o método finish().
- Ver liña 33 do código.
- Como exercicio, podedes ir lendo a sección Recrear unha actividade: gardar e recuperar o seu estado e facer que cando rotades o dispositivo o Cronómetro continúe no mesmo punto onde estaba.
Enlace a la página principal de la UD2
Enlace a la página principal del curso
-- Ángel D. Fernández González e Carlos Carrión Álvarez -- (2015).