Diferencia entre revisiones de «Flutter Diálogos»

De MediaWiki
Ir a la navegación Ir a la búsqueda
Línea 99: Línea 99:
 
<br />
 
<br />
  
−
==DatePickerDialog==
+
==DatePicker / TimePicker==
 +
 
 +
* Más información:
 +
:* https://api.flutter.dev/flutter/material/DatePickerDialog-class.html
 +
:* https://api.flutter.dev/flutter/material/showDatePicker.html
 +
 
 +
:* https://api.flutter.dev/flutter/material/TimePickerDialog-class.html
 +
:* https://api.flutter.dev/flutter/material/showTimePicker.html
 +
 
 +
 
 +
* Creamos una nueva página en la [https://wiki.cifprodolfoucha.es/index.php?title=Flutter_Widget#Estructura_de_p.C3.A1ginas carpeta pages] de nombre '''formulario_page.dart'''
 +
: En todas las páginas haremos lo mismo:
 +
:* Importamos la librería de 'material' (recordar que existe un [https://github.com/marius-h/flutter_enhancement_suite/blob/main/SNIPPETS.md#flutter-widget-snippets snippet] que lo hace automático).
 +
:* Creamos una clase (FormularioPage) que derive de '''StatefulWidget'''. Se creará (si lo hacéis con un Snippet) una clase asociada que deriva de State.
 +
:* Modificamos la clase State y en su métod build hacemos que devuelva un Scaffold con una Appbar (hacerlo con un Snippet)
 +
 
 +
 
 +
 
 +
 
 +
* Estos dos elementos gráficos muestran una ventana modal con controles gráficos para escojer una fecha / hora según el caso.
 +
: Normalmente se muestra al usuario un TextField inhabilitado (con el parámetro readonly a true o el parámetro enableInteractiveSelection a false) y al pulsar sobre el mismo se muestra la ventana modal para que escoja la fecha / hora. Una vez escojida, se cierra la ventana modal y se muestra la fecha / hora en la caja de texto.
 +
 
 +
 
 +
* El tipo de dato que vamos a recoger de la ventana modal del DatePickerDialog va a ser un [https://api.flutter.dev/flutter/dart-core/DateTime-class.html objeto de la clase DateTime].
 +
: Este devuelve la fecha-hora conjuntamente. Como para cada control vamos a querer mostrar sólo la fecha o sólo la hora, podemos hacer uso del [https://pub.dev/packages/intl paquete intl] el cual nos permite extraer parte del DateTime (lo que nos interese) y guardarlo en forma de String. Para instalarlo debéis seguir los [https://pub.dev/packages/intl/install pasos indicados en la pestaña de instalación].
 +
: El tipo de dato que vamos a recoger de la ventana modal del TimePickerDialog va a ser un [https://api.flutter.dev/flutter/material/TimeOfDay-class.html TimeOfDay]. Vamos a necesitar crear un DateTime con la hora-minuto recojida de este control y aplicar la función DateFormat del paquete anterior para mostrar sólo la hora y el minuto.
 +
 
 +
 
 +
* En este caso, cuando volvemos de seleccionar una fecha - hora con la ventana modal, recojeremos el resultado de la selección, pero necesitamos modificar el contenido de las cajas de texto donde van a ir esos datos.
 +
: Para hacerlo necesitamos:
 +
:* Crear un objeto de la [https://api.flutter.dev/flutter/widgets/TextEditingController-class.html clase TextEditingController] (un objeto para cada caja que queramos modificar su contenido, en este ejemplo dos, uno para la hora y otro para la fecha.
 +
:* Asociar dicho controlador a cada una de las cajas de texto. Esto se consigue en el parámetro del constructor [https://api.flutter.dev/flutter/material/TextField/controller.html controller] del TextField.
 +
:* Desde el método que nos devuelve el resultado de escojer la fecha / hora podemos modificar el contenido con la [https://api.flutter.dev/flutter/widgets/TextEditingController/text.html propiedad text] del controlador.
 +
 
 +
 
 +
 
 +
* En el ejemplo aparecen dos cajas de texto que al pulsar encima de ellas, en una aparece la ventana modal para seleccionar una fecha y en el otro para seleccionar un hora-minuto.
 +
[[Imagen:Flutter_dart_formulario_9.JPG|300px|center]]
 +
 
 +
 
 +
:<syntaxhighlight lang="java" enclose="div" highlight="17,18,28,29,54,73-74,79-115,117-129,131-147" >
 +
import 'package:intl/intl.dart';
 +
import 'package:flutter/material.dart';
 +
import 'package:flutter/services.dart';
 +
 
 +
class FormularioPage extends StatefulWidget {
 +
  const FormularioPage({Key? key}) : super(key: key);
 +
 
 +
  @override
 +
  _FormularioPageState createState() => _FormularioPageState();
 +
}
 +
 
 +
 
 +
class _FormularioPageState extends State<FormularioPage> {
 +
  String _nombre = '';
 +
  String _email = '';
 +
  String _password = '';
 +
  String _fechaEscojida = '';
 +
  String _horaEscojida = '';
 +
 
 +
  List<String> _optTipoPaciente = ['Crónico', 'Terminal', 'Observación'];
 +
  String _valorEscojidoTipoPaciente = 'Crónico';
 +
 
 +
  bool _checkEnfermedadTerminal = false;
 +
  bool _switchHospitalizado = false;
 +
  String _radioAtenciomInicial='';
 +
  Set<String> _valoresRadio = {'Cabecera', 'Uci', 'Urgencias'};
 +
 
 +
  TextEditingController _inputFieldDateController = new TextEditingController();
 +
  TextEditingController _inputFieldTimeController = new TextEditingController();
 +
 
 +
  @override
 +
  Widget build(BuildContext context) {
 +
    return Scaffold(
 +
        appBar: AppBar(
 +
          title: Text('Formulario'),
 +
        ),
 +
        body: ListView(
 +
          padding: EdgeInsets.symmetric(horizontal: 5.0,vertical: 10.0),
 +
          children: [
 +
            _crearInput(),    // TextField con múltiples opciones de decoración
 +
            Divider(),
 +
            _crearEmail(),
 +
            Divider(),
 +
            _crearPassword(),
 +
            Divider(),
 +
            _crearDropDown(),
 +
            Divider(),
 +
            _crearCheckBox(),
 +
            Divider(),
 +
            _crearSwitch(),
 +
            Divider(),
 +
            _crearRadio(),
 +
            Divider(),
 +
            _DatePickerTimePicker(),
 +
            Divider(),
 +
            Divider(),
 +
            _visualizarDatos(),
 +
 
 +
          ],
 +
        ));
 +
  }
 +
 
 +
  Widget _visualizarDatos(){
 +
    return Column(
 +
      children: [
 +
        Text('Nombre del paciente: $_nombre'),
 +
        Text('Email del paciente: $_email'),
 +
        Text('Password: $_password'),
 +
        Text('Tipo de paciente: $_valorEscojidoTipoPaciente'),
 +
        Text('Enfermedad terminal: $_checkEnfermedadTerminal'),
 +
        Text('Hospitalizado: $_switchHospitalizado'),
 +
        Text('Atendido inicialmente en: $_radioAtenciomInicial'),
 +
        Text('Fecha escojida: $_fechaEscojida'),
 +
        Text('Hora escojida: $_horaEscojida'),
 +
      ],
 +
    );
 +
  }
 +
 
 +
  Widget _DatePickerTimePicker(){
 +
 
 +
    return
 +
        Column(
 +
          children: [
 +
            TextField(
 +
              controller: _inputFieldDateController,
 +
              decoration: InputDecoration(
 +
                  hintText: 'Fecha de ingreso',
 +
                  labelText: 'Fecha de ingreso',
 +
                  suffixIcon: Icon(Icons.date_range),
 +
                  border: OutlineInputBorder(
 +
                    borderRadius: BorderRadius.circular(15.0),
 +
                  )
 +
              ),
 +
              readOnly: true,
 +
              onTap: () => _mostrarDatePicker(),
 +
            ),
 +
            SizedBox(height: 10.0,),
 +
            TextField(
 +
              controller: _inputFieldTimeController,
 +
              decoration: InputDecoration(
 +
                  hintText: 'Hora de ingreso',
 +
                  labelText: 'Hora de ingreso',
 +
                  suffixIcon: Icon(Icons.timelapse),
 +
                  border: OutlineInputBorder(
 +
                    borderRadius: BorderRadius.circular(15.0),
 +
                  )
 +
              ),
 +
              readOnly: true,
 +
              onTap: () => _mostrarTimePicker(),
 +
            ),
 +
 
 +
          ],
 +
        );
 +
 
 +
  }
 +
 
 +
  void _mostrarDatePicker(){
 +
    // Podríamos poner async en la definición y llamar con un await para que devuelva un DateTime
 +
    showDatePicker(context: context, initialDate: DateTime.now(), firstDate: DateTime(1995),lastDate: DateTime(2024),
 +
        helpText: 'Fecha de ingreso')
 +
      .then((value){
 +
        setState(() {  // Necesitamos redibujar el texto para que muestre la fecha
 +
          if (value !=null) {
 +
            _fechaEscojida = DateFormat('dd-MM-yyyy').format(value);
 +
            _inputFieldDateController.text = _fechaEscojida;
 +
          }
 +
        });
 +
      });
 +
  }
 +
 
 +
  void _mostrarTimePicker(){
 +
    // Podríamos poner async en la definición y llamar con un await para que devuelva un DateTime
 +
    showTimePicker(context: context, initialTime: TimeOfDay(hour: DateTime.now().hour, minute: DateTime.now().minute),
 +
        helpText: 'Hora de ingreso')
 +
        .then((value){
 +
      setState(() {  // Necesitamos redibujar el texto para que muestre la hora
 +
        if (value !=null) {
 +
          // Convertimos el formato TimeOfDay a HH:mm  Podríamos crear una función para reutilizar siempre que sea necesario
 +
          final ahora = DateTime.now();
 +
          final dt = new DateTime(ahora.year,ahora.month,ahora.day,value.hour,value.minute);
 +
          final formato = DateFormat.jm();  // Formato HH:mm AM
 +
          _horaEscojida = formato.format(dt);
 +
          _inputFieldTimeController.text = _horaEscojida;
 +
        }
 +
      });
 +
    });
 +
  }
 +
 
 +
  Widget _crearRadio(){
 +
 
 +
    return Column(
 +
      mainAxisAlignment: MainAxisAlignment.center,
 +
      children: _elemsRadio(),
 +
    ) ;
 +
  }
 +
 
 +
  List<Widget>_elemsRadio(){
 +
    List<Widget> lista = [];
 +
    _valoresRadio.forEach((element) {
 +
      RadioListTile r = RadioListTile(
 +
          title: Text(element),
 +
          value: element,
 +
          groupValue: _radioAtenciomInicial,
 +
          onChanged: (valor){ setState(() {
 +
            _radioAtenciomInicial = valor;
 +
          });},
 +
        );
 +
        lista.add(r);
 +
    });
 +
    return lista;
 +
  }
 +
 
 +
  Widget _crearSwitch(){
 +
    return SwitchListTile(
 +
        title: Text('Hospitalizado'),
 +
        subtitle: Text('Indica si está hospitalizado'),
 +
        secondary: Icon(Icons.accessibility),
 +
        value: _switchHospitalizado,
 +
        onChanged: (valor) { setState(() {
 +
          _switchHospitalizado = valor;
 +
        }); });
 +
  }
 +
  Widget _crearCheckBox(){
 +
    return CheckboxListTile(
 +
        title: Text('Enfermedad terminal'),
 +
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0),side: BorderSide(color: Colors.grey)),
 +
        value: _checkEnfermedadTerminal,
 +
        onChanged: (nuevoValor) {  // Hay que llamar a setState para que redibuje el CheckBox
 +
          setState(() { _checkEnfermedadTerminal = nuevoValor! ;});
 +
        }
 +
 
 +
    );
 +
  }
 +
  Widget _crearDropDown(){
 +
    return Container(
 +
      height: 60.0,
 +
      padding: EdgeInsets.only(left: 8.0),
 +
      decoration: BoxDecoration(
 +
        borderRadius: BorderRadius.circular(15.0),
 +
        border: Border.all(
 +
          color: Colors.grey
 +
        )
 +
      ),
 +
      child: Row(
 +
        children: [
 +
          DropdownButton(
 +
            value: _valorEscojidoTipoPaciente,
 +
            onChanged: (String? valor) { setState(() { _valorEscojidoTipoPaciente = valor!; });},
 +
            items: _crearItemsDropDown(),
 +
 
 +
          ),
 +
          Spacer(),
 +
          Container(child: Icon(Icons.api),
 +
                    padding: EdgeInsets.only(right: 10.0),
 +
          ),
 +
        ],
 +
      ),
 +
    );
 +
  }
 +
 
 +
  List<DropdownMenuItem<String>> _crearItemsDropDown(){
 +
 
 +
    List<DropdownMenuItem<String>> lista = [];
 +
    _optTipoPaciente.forEach((element) {
 +
      lista.add(DropdownMenuItem(child: Text('$element'),value: element,));
 +
    });
 +
 
 +
    return lista;
 +
  }
 +
 
 +
  Widget _crearEmail(){
 +
 
 +
    return TextField(
 +
      onChanged: (valor) => setState((){
 +
                                        _email = valor;
 +
                                        print(valor);}
 +
                                    ),  // Fijarse que podemos guardar una cadena vacía
 +
      keyboardType: TextInputType.emailAddress,
 +
      decoration: InputDecoration(
 +
        hintText: 'Email del paciente',
 +
        labelText: 'Email',
 +
        suffixIcon: Icon(Icons.email),
 +
        border: OutlineInputBorder(
 +
          borderRadius: BorderRadius.circular(15.0),
 +
        )
 +
      ),
 +
    );
 +
  }
 +
 
 +
 
 +
  Widget _crearPassword(){
 +
 
 +
    return TextField(
 +
      onChanged: (valor) => setState((){_password = valor;}),  // Fijarse que podemos guardar una cadena vacía
 +
      obscureText: true,
 +
      obscuringCharacter: '-',
 +
      maxLength: 20,
 +
      decoration: InputDecoration(
 +
          hintText: 'Password de entrada',
 +
          labelText: 'Password',
 +
          suffixIcon: Icon(Icons.password),
 +
          border: OutlineInputBorder(
 +
            borderRadius: BorderRadius.circular(15.0),
 +
          )
 +
      ),
 +
    );
 +
  }
 +
 
 +
  Widget _crearInput() {
 +
 
 +
    return TextField(
 +
      onChanged: (valor) => setState((){_nombre = valor;}),  // Fijarse que podemos guardar una cadena vacía
 +
      textCapitalization: TextCapitalization.words,
 +
      keyboardType: TextInputType.name,
 +
      decoration: InputDecoration(
 +
        border: OutlineInputBorder(    // Establece un borde cicular/otro  alrededor de la caja de texto
 +
          borderRadius: BorderRadius.circular(15.0),
 +
        ),
 +
        counterText: 'Número de caracteres: ${_nombre.length}',  // Texto que aparece a la derecha y debajo de la caja
 +
        hintText: 'Nombre del paciente',          // Texto que aparece dentro de la caja y desaparece al escribir
 +
        labelText: 'Nombre',                      // Texto qye aparece encima de la caja AL PULSAR EN EL INTERIOR PARA ESCRIBIR
 +
        helperText: 'Introduce el nombre del paciente',  // Texto que aparece a la izquierda y abajo de la caja
 +
        suffixIcon: Icon(Icons.access_alarm),    // Widget que aparece a la derecha dentro de la caja
 +
        icon: Icon(Icons.accessibility),          // Widget que aparece a la izquierda fuera de la caja
 +
 
 +
      ),
 +
    );
 +
 
 +
  }
 +
 
 +
}
 +
 
 +
 
 +
</syntaxhighlight>
 +
 
 +
 
 +
 
 +
 
 +
* <u>'''NOTA:</u>''' Si quieréis hacer que el DatePicker y TimePicker estén en español, seguir [https://wiki.cifprodolfoucha.es/index.php?title=Flutter_Internacionalizaci%C3%B3n lo indicado en este enlace de la Wiki]
 +
 
 +
 
 +
<br />
 +
 
 +
 
  
  
 
<br />
 
<br />
 +
 
==TimePickerDialog==
 
==TimePickerDialog==
  

Revisión del 17:48 22 sep 2021

Intruducción

  • Los díalogos suelen ser ventanas modales (no se puede iteraccionar con la aplicación hasta que se cierre) en los que:
  • Se informa de algo
  • Se solicita información al usuario.


  • Creamos una nueva página en la carpeta pages de nombre alert_pages.dart
En todas las páginas haremos lo mismo:
  • Importamos la librería de 'material' (recordar que existe un snippet que lo hace automático).
  • Creamos una clase que derive de StatelessWidget (al hacerlo será necesario implementar el método build, ya os da un aviso el Android Studio) de nombre AlertPage.
  • Dentro del método build, retornamos un widget Scaffold (recordar que existe un snippet que lo hace automático).


  • En todos los tipos de diálogos vamos a tener que 'mostrarlo'. Para ello vamos a hacer uso de la clase showDialog a la que vamos a tener que:
  • Enviar en forma de parámetro el buildcontext.
  • Devolver el Widget que queremos que se visualice como 'contenido' del diálogo. Esto lo indicamos en el parámetro builder.
  • barrierDismissible: Indicamos si queremos que se pueda cerrar el diálogo al pulsar fuera del mismo (por defecto es true).


Al instanciar esta clase, se devuelve un Future. En dicho Future puede venir información sobre qué opción fue pulsada por parte del usuario (al cerrar al diálogo con el método pop de la clase Navigator, se puede enviar información de vuelta a quien llamó al showDialog).



AlertDialog

  • Este tipo de diálogos suelen ser empleados para informar al usuario de algo o para que escoga entre un número limitado de opciones (normalmente dos) la acción a seguir.
Los parámetros más importantes son:
  • title: Título de la alerta.
  • content: Contenido de la alerta.
  • actions: Lista de widget que van a conformar las 'acciones' que va a tener el alertdialog. Normalmente son botones.
Para cerrar el diálogo podemos hacer uso del método pop de la clase Navigator.


  • Veamos un ejemplo:
Flutter dart alert 1.JPG



import 'package:flutter/material.dart';

class AlertPage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Ejemplos de Alert'),
        ),
        body: Row (
          mainAxisAlignment:MainAxisAlignment.center,
          children: [
            TextButton(
              onPressed: () => _mostrarAlerta1(context).then((value) => print(value)),    // El then no es obligatorio. Lo pondríamos si queremos recibir información de vuelta
              child: Text('Alerta 1',style: TextStyle(color: Colors.yellow),),
              style: ElevatedButton.styleFrom(primary: Colors.blue,shape: StadiumBorder())
            )
          ],
        )
    );
  }

  Future _mostrarAlerta1(BuildContext context){    // Si no vamos a 'devolver' información podríamos definir el método como void y no hacer el return del showDialog.
       return showDialog(context: context,
                 builder: (BuildContext context) {
                    return AlertDialog(
                      title: Text('Título del diálogo'),
                      content: Column(
                        mainAxisSize: MainAxisSize.min, // Para que la columna no ocupe todo el alto de la pantalla
                        children: [
                          Text('Contenido del diálogo. Texto que queramos que aparezca para informar al usuario de algo'),
                          FlutterLogo(size: 50,)
                        ],
                      ),
                      actions: [
                        TextButton(onPressed: () => Navigator.pop(context), child: Text('Cancelar')), // Cerramos el diálogo
                        TextButton(onPressed: (){
                          // Pondríamos el código que queramos
                          Navigator.pop(context,'Valor de vuelta');     // Envío de vuelta a quien llamó la información que quiera. NO ES OBLIGATORIO
                        }, child: Text('Aceptar')),

                      ],
                    );;
        },
      );
  }
}



DatePicker / TimePicker

  • Más información:


  • Creamos una nueva página en la carpeta pages de nombre formulario_page.dart
En todas las páginas haremos lo mismo:
  • Importamos la librería de 'material' (recordar que existe un snippet que lo hace automático).
  • Creamos una clase (FormularioPage) que derive de StatefulWidget. Se creará (si lo hacéis con un Snippet) una clase asociada que deriva de State.
  • Modificamos la clase State y en su métod build hacemos que devuelva un Scaffold con una Appbar (hacerlo con un Snippet)



  • Estos dos elementos gráficos muestran una ventana modal con controles gráficos para escojer una fecha / hora según el caso.
Normalmente se muestra al usuario un TextField inhabilitado (con el parámetro readonly a true o el parámetro enableInteractiveSelection a false) y al pulsar sobre el mismo se muestra la ventana modal para que escoja la fecha / hora. Una vez escojida, se cierra la ventana modal y se muestra la fecha / hora en la caja de texto.


Este devuelve la fecha-hora conjuntamente. Como para cada control vamos a querer mostrar sólo la fecha o sólo la hora, podemos hacer uso del paquete intl el cual nos permite extraer parte del DateTime (lo que nos interese) y guardarlo en forma de String. Para instalarlo debéis seguir los pasos indicados en la pestaña de instalación.
El tipo de dato que vamos a recoger de la ventana modal del TimePickerDialog va a ser un TimeOfDay. Vamos a necesitar crear un DateTime con la hora-minuto recojida de este control y aplicar la función DateFormat del paquete anterior para mostrar sólo la hora y el minuto.


  • En este caso, cuando volvemos de seleccionar una fecha - hora con la ventana modal, recojeremos el resultado de la selección, pero necesitamos modificar el contenido de las cajas de texto donde van a ir esos datos.
Para hacerlo necesitamos:
  • Crear un objeto de la clase TextEditingController (un objeto para cada caja que queramos modificar su contenido, en este ejemplo dos, uno para la hora y otro para la fecha.
  • Asociar dicho controlador a cada una de las cajas de texto. Esto se consigue en el parámetro del constructor controller del TextField.
  • Desde el método que nos devuelve el resultado de escojer la fecha / hora podemos modificar el contenido con la propiedad text del controlador.


  • En el ejemplo aparecen dos cajas de texto que al pulsar encima de ellas, en una aparece la ventana modal para seleccionar una fecha y en el otro para seleccionar un hora-minuto.
Flutter dart formulario 9.JPG


import 'package:intl/intl.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class FormularioPage extends StatefulWidget {
  const FormularioPage({Key? key}) : super(key: key);

  @override
  _FormularioPageState createState() => _FormularioPageState();
}


class _FormularioPageState extends State<FormularioPage> {
  String _nombre = '';
  String _email = '';
  String _password = '';
  String _fechaEscojida = '';
  String _horaEscojida = '';

  List<String> _optTipoPaciente = ['Crónico', 'Terminal', 'Observación'];
  String _valorEscojidoTipoPaciente = 'Crónico';

  bool _checkEnfermedadTerminal = false;
  bool _switchHospitalizado = false;
  String _radioAtenciomInicial='';
  Set<String> _valoresRadio = {'Cabecera', 'Uci', 'Urgencias'};

  TextEditingController _inputFieldDateController = new TextEditingController();
  TextEditingController _inputFieldTimeController = new TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Formulario'),
        ),
        body: ListView(
          padding: EdgeInsets.symmetric(horizontal: 5.0,vertical: 10.0),
          children: [
            _crearInput(),    // TextField con múltiples opciones de decoración
            Divider(),
            _crearEmail(),
            Divider(),
            _crearPassword(),
            Divider(),
            _crearDropDown(),
            Divider(),
            _crearCheckBox(),
            Divider(),
            _crearSwitch(),
            Divider(),
            _crearRadio(),
            Divider(),
            _DatePickerTimePicker(),
            Divider(),
            Divider(),
            _visualizarDatos(),

          ],
        ));
  }

  Widget _visualizarDatos(){
    return Column(
      children: [
        Text('Nombre del paciente: $_nombre'),
        Text('Email del paciente: $_email'),
        Text('Password: $_password'),
        Text('Tipo de paciente: $_valorEscojidoTipoPaciente'),
        Text('Enfermedad terminal: $_checkEnfermedadTerminal'),
        Text('Hospitalizado: $_switchHospitalizado'),
        Text('Atendido inicialmente en: $_radioAtenciomInicial'),
        Text('Fecha escojida: $_fechaEscojida'),
        Text('Hora escojida: $_horaEscojida'),
      ],
    );
  }

  Widget _DatePickerTimePicker(){

    return
        Column(
          children: [
            TextField(
              controller: _inputFieldDateController,
              decoration: InputDecoration(
                  hintText: 'Fecha de ingreso',
                  labelText: 'Fecha de ingreso',
                  suffixIcon: Icon(Icons.date_range),
                  border: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(15.0),
                  )
              ),
              readOnly: true,
              onTap: () => _mostrarDatePicker(),
            ),
            SizedBox(height: 10.0,),
            TextField(
              controller: _inputFieldTimeController,
              decoration: InputDecoration(
                  hintText: 'Hora de ingreso',
                  labelText: 'Hora de ingreso',
                  suffixIcon: Icon(Icons.timelapse),
                  border: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(15.0),
                  )
              ),
              readOnly: true,
              onTap: () => _mostrarTimePicker(),
            ),

          ],
        );

  }

  void _mostrarDatePicker(){
    // Podríamos poner async en la definición y llamar con un await para que devuelva un DateTime
    showDatePicker(context: context, initialDate: DateTime.now(), firstDate: DateTime(1995),lastDate: DateTime(2024),
        helpText: 'Fecha de ingreso')
      .then((value){
        setState(() {   // Necesitamos redibujar el texto para que muestre la fecha
          if (value !=null) {
            _fechaEscojida = DateFormat('dd-MM-yyyy').format(value);
            _inputFieldDateController.text = _fechaEscojida;
          }
        });
      });
  }

  void _mostrarTimePicker(){
    // Podríamos poner async en la definición y llamar con un await para que devuelva un DateTime
    showTimePicker(context: context, initialTime: TimeOfDay(hour: DateTime.now().hour, minute: DateTime.now().minute),
        helpText: 'Hora de ingreso')
        .then((value){
      setState(() {   // Necesitamos redibujar el texto para que muestre la hora
        if (value !=null) {
          // Convertimos el formato TimeOfDay a HH:mm  Podríamos crear una función para reutilizar siempre que sea necesario
          final ahora = DateTime.now();
          final dt = new DateTime(ahora.year,ahora.month,ahora.day,value.hour,value.minute);
          final formato = DateFormat.jm();  // Formato HH:mm AM
          _horaEscojida = formato.format(dt);
          _inputFieldTimeController.text = _horaEscojida;
        }
      });
    });
  }

  Widget _crearRadio(){

    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: _elemsRadio(),
    ) ;
  }

  List<Widget>_elemsRadio(){
    List<Widget> lista = [];
    _valoresRadio.forEach((element) {
      RadioListTile r = RadioListTile(
          title: Text(element),
          value: element,
          groupValue: _radioAtenciomInicial,
          onChanged: (valor){ setState(() {
            _radioAtenciomInicial = valor;
          });},
        );
        lista.add(r);
    });
    return lista;
  }

  Widget _crearSwitch(){
    return SwitchListTile(
        title: Text('Hospitalizado'),
        subtitle: Text('Indica si está hospitalizado'),
        secondary: Icon(Icons.accessibility),
        value: _switchHospitalizado,
        onChanged: (valor) { setState(() {
          _switchHospitalizado = valor;
        }); });
  }
  Widget _crearCheckBox(){
    return CheckboxListTile(
        title: Text('Enfermedad terminal'),
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0),side: BorderSide(color: Colors.grey)),
        value: _checkEnfermedadTerminal,
        onChanged: (nuevoValor) {   // Hay que llamar a setState para que redibuje el CheckBox
          setState(() { _checkEnfermedadTerminal = nuevoValor! ;});
        }

    );
  }
  Widget _crearDropDown(){
    return Container(
      height: 60.0,
      padding: EdgeInsets.only(left: 8.0),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(15.0),
        border: Border.all(
          color: Colors.grey
        )
      ),
      child: Row(
        children: [
          DropdownButton(
            value: _valorEscojidoTipoPaciente,
            onChanged: (String? valor) { setState(() { _valorEscojidoTipoPaciente = valor!; });},
            items: _crearItemsDropDown(),

          ),
          Spacer(),
          Container(child: Icon(Icons.api),
                    padding: EdgeInsets.only(right: 10.0),
          ),
        ],
      ),
    );
  }

  List<DropdownMenuItem<String>> _crearItemsDropDown(){

    List<DropdownMenuItem<String>> lista = [];
    _optTipoPaciente.forEach((element) {
       lista.add(DropdownMenuItem(child: Text('$element'),value: element,));
    });

    return lista;
  }

  Widget _crearEmail(){

    return TextField(
      onChanged: (valor) => setState((){
                                        _email = valor;
                                        print(valor);}
                                    ),   // Fijarse que podemos guardar una cadena vacía
      keyboardType: TextInputType.emailAddress,
      decoration: InputDecoration(
        hintText: 'Email del paciente',
        labelText: 'Email',
        suffixIcon: Icon(Icons.email),
        border: OutlineInputBorder(
          borderRadius: BorderRadius.circular(15.0),
        )
      ),
    );
  }


  Widget _crearPassword(){

    return TextField(
      onChanged: (valor) => setState((){_password = valor;}),   // Fijarse que podemos guardar una cadena vacía
      obscureText: true,
      obscuringCharacter: '-',
      maxLength: 20,
      decoration: InputDecoration(
          hintText: 'Password de entrada',
          labelText: 'Password',
          suffixIcon: Icon(Icons.password),
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(15.0),
          )
      ),
    );
  }

  Widget _crearInput() {

    return TextField(
      onChanged: (valor) => setState((){_nombre = valor;}),   // Fijarse que podemos guardar una cadena vacía
      textCapitalization: TextCapitalization.words,
      keyboardType: TextInputType.name,
      decoration: InputDecoration(
        border: OutlineInputBorder(     // Establece un borde cicular/otro  alrededor de la caja de texto
          borderRadius: BorderRadius.circular(15.0),
        ),
        counterText: 'Número de caracteres: ${_nombre.length}',   // Texto que aparece a la derecha y debajo de la caja
        hintText: 'Nombre del paciente',          // Texto que aparece dentro de la caja y desaparece al escribir
        labelText: 'Nombre',                      // Texto qye aparece encima de la caja AL PULSAR EN EL INTERIOR PARA ESCRIBIR
        helperText: 'Introduce el nombre del paciente',  // Texto que aparece a la izquierda y abajo de la caja
        suffixIcon: Icon(Icons.access_alarm),     // Widget que aparece a la derecha dentro de la caja
        icon: Icon(Icons.accessibility),          // Widget que aparece a la izquierda fuera de la caja

      ),
    );

  }

}








TimePickerDialog


Enlace a la página principal de la UD5

Enlace a la página principal del curso




-- Ángel D. Fernández González -- (2021).