CURSO DE FLUTTER
Contenido
- Tipos de datos
- Casting
- Sintaxis
- Qué es un widget
- Qué es MaterialApp
- Qué es Scaffold
- StatelessWidget
- StatefulWidget
- Propiedades en APPBAR
- Propiedades en BODY
- Widgets
- Botones
- Routes
- Navigator
- Recibir argumentos de rutas
- Eventos o GestureDetector
- Validacion de formulario
- Tipos de teclado
- Drawer completo
- Notificacion snackbar
- Otros comandos
PROGRAMAS A UTILIZAR
- Visual Studio Code Es un editor de codigo fuente desarrollado por Microsoft. Utilizaremos este programa por que es más ligero y tiene mas opciones a diferencia de otros
REQUISITOS BÁSICOS
- Lógica de programacion
CONCEPTOS BÁSICOS
Flutter
es un kit de herramientas de UI(interfaz de usuario) de google para realizar
hermosas aplicaciones
nativamente, para movil, web y escritorio desde una unica base de codigo
- Rapido desarrollo (android-ios)
- Interface de usuario expresiva y flexible (widget->control total)
- Alto rendimiento
EXTENSIONES vsc
- Flutter
- flutter widget snippets
- awesome flutter snippets
CONFIGURACION
- Paso 1
- instalar SDK
- descomprimir
- copiar la carpeta flutter en el disco C:
- Paso 2
- buscar en inicio (variables de entorno)
- click en variables de entorno
- editar en PATH
- agregar la siguiente (C:\flutter\bin)
- Paso 3
- probar que flutter funcione
- ejecuta en CMD (flutter doctor)
- es necesario que ejecutes desde C:users/I3
- se descargaran algunos packetes
- ejecuta para LA LICENCIA (flutter doctor --android-licenses)
- reinicia VSC
- Paso 4 Instalar
Genymotion
- Instalar VirtualBox
- Instalar Genymotion
- Nuevo proyecto
- (VSC) click en ver
- paleta de comandos
- flutter
- nuevo proyecto
- select device(para agregar un dispositivo)
- si aparece un error de gradle -> por favor elija bien el EMULADOR
TIPOS DE DATOS
- int
- double
- String
- bool
- dynamic
- List<String> nombres = ["isai", "juan", "pedro", "maria", "jose"];
- var
CASTING
- cadena a int
- cadena para double
- int a cadena
- double a cadena
// String to int
var one = int.parse('1');
// String to double
var onePointOne = double.parse('1.1');
// int to String
String twenty = 20.toString();
// double to String
String pi= 3.14316.toStringAsFixed(2);
SINTAXIS
//Nos permite trabajar con los diseños de layouts de Material Design
import 'package:flutter/material.dart';
//Es el primer metodo en ejecutarse al correr(ejecutar) la APK
void main() {
runApp(MiApp());
}
class MiApp extends StatelessWidget {
const MiApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "app",
home: Inicio(),
);
}
}
class Inicio extends StatefulWidget {
Inicio({Key key}) : super(key: key);
@override
_InicioState createState() => _InicioState();
}
class _InicioState extends State<Inicio> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Menu de navegacion"),
),
body: Center(
child: Text("hola mundo"),
),
);
}
}
QUE ES UN WIDGET
Un widget es un elemento de una interfaz gráfica de usuario.
return MaterialApp(
title: "App",
home: Inicio(),
);
QUE ES MaterialApp
MaterialApp es un widget que nos proporciona un layout orientado a
Material Design. Para
utilizarlo, en la llamada al método runApp creamos una nueva instancia y se lo
pasamos de la siguiente
forma. El widget MaterialApp tiene como atributos entre otros: title El título de la
app.
return MaterialApp(
title: "App",
home: Inicio(),
);
QUE ES Scaffold
Es una estructura que nos permite organizar nuestras pantallas.
Es la parte donde se encuentra todo el contenido que se va a mostrar
en la pantalla. Un
Scaffold puede contener las siguientes propiedades
- appBar
- backgroundColor
- body
- bottomNavigationBar
- drawer
- endDrawer
- floatingActionButtom
- bottomSheet
return Scaffold(
appBar: AppBar(
title: Text("Sandoval Apk"),
),
body: Text("Hola mundo"),
drawer: Drawer(),
endDrawer: Drawer(),
backgroundColor: Colors.red,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {},
),
);
StatelessWidget
Es un widget sin estado o tambien llamado constante; Es
considerado de esa forma
porque todos los contenidos que están dentro NO pueden cambiar su valor en tiempo de
ejecucion.
class MiApp extends StatelessWidget {
const MiApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "App",
home: Inicio(),
);
}
}
StatefulWidget
Es un widget con estado es todo lo contrario del
StatelessWidget. En este caso los
contenidos que entán dentro SI pueden cambiar de valor en tiempo de
ejecucion.
class Inicio extends StatefulWidget {
Inicio({Key key}) : super(key: key);
@override
_InicioState createState() => _InicioState();
}
class _InicioState extends State<Inicio> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Sandoval Apk"),
),
body: Text("Hola mundo"),
);
}
@override
void initState() {
//TODO code here
super.initState();
}
@override
void dispose() {
//TODO code here
super.dispose();
}
}
PROPIEDADES EN APPBAR
- LEADING
- TITLE
- ACCION
- BACKGROUNDCOLOR
- ELEVATION
- SHAPE
TITLE nos permite agregar un titulo
title: Text("Sandoval Apk"),
ACCION nos permite agregar botones en la parte
derecha
actions: <Widget>[
IconButton(
icon: Icon(Icons.add),
onPressed: () {
_agregar();
},
),
IconButton(
icon: Icon(Icons.remove),
onPressed: () {
_quitar();
},
),
],
BACKGROUNDCOLOR nos permite agregar color de fondo
backgroundColor: Colors.red, //color de fondo
LEADING agregar boton de volver atras
leading: IconButton(
//boton volver atras
icon: Icon(
Icons.arrow_back,
),
onPressed: () {},
),
ELEVATION nos permite agregar sombre del appBar
elevation: 100, //es la sombra
SHAPE nos permite agregar bordes redondeados
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5),
),
PROPIEDADES EN BODY
- ICON
- TEXT
ICON nos permite agregar iconos
body: Icon(
Icons.close,
size: 50.0,
//color: Colors.red,
//color: Theme.of(context).primaryColor,
color: Color.fromRGBO(0, 0, 255, 1),
),
TEXT nos permite agregar textos
body: Text(
"Hola Mundo",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.green,
backgroundColor: Colors.black,
fontSize: 25.0,
fontStyle: FontStyle.italic,
decoration: TextDecoration.underline,
fontWeight: FontWeight.bold,
),
),
WIDGETS
LIST VIEW
List<String> nombres = ["isai", "juan", "pedro", "maria", "jose"];
body: ListView.builder(
itemCount: nombres.length,
itemBuilder: (BuildContext context, int index) {
return Card(
child: Text(
nombres[index],
),
);
},
),
IMAGE
assets:
- assets/img1.png
// en pubspec.yaml
Image.network("https://sm.ign.com/t/ign_latam/screenshot/default/naruto4_st6s.1280.jpg"),
Image.asset("./assets/img1.png"),
TEXT FIELD
// CAMPO TIPO NUMERICO
body: TextField(
keyboardType: TextInputType.number,
style: Theme.of(context).textTheme.headline6, //tamaño de texto
decoration: InputDecoration(
icon: Icon(Icons.account_circle, size: 20),
labelText: "Ingrese su numero",
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(5.0),
)),
),
),
// CAMPO TIPO TEXT-AREA
body: TextField(
maxLines: 10,
textCapitalization: TextCapitalization.sentences,
decoration: InputDecoration(
counterText: "palabras",
labelText: "Comentarios",
hintText: "Este es el placeholder",
border: const OutlineInputBorder(),
),
),
// CAMPO TIPO PASSWORD
class _InicioState extends State<Inicio> {
@override
bool verClave = false;
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Menu de navegacion"),
),
body: TextField(
obscureText: !this.verClave,
decoration: InputDecoration(
labelText: "Contraseña",
prefixIcon: const Icon(
Icons.security,
),
suffixIcon: IconButton(
icon: Icon(
Icons.remove_red_eye,
color: this.verClave ? Colors.blue : Colors.grey,
),
onPressed: () {
setState(() {
this.verClave = !this.verClave;
});
},
),
hintText: "Este es el placeholder",
border: const OutlineInputBorder(),
),
),
);
}
}
TEXT FORM FIELD
// NOMBRE DE USUARIO
body: TextFormField(
textCapitalization: TextCapitalization.words,
decoration: const InputDecoration(
border: UnderlineInputBorder(),
filled: true,
icon: Icon(Icons.person),
hintText: 'Cual es tu nombre',
labelText: 'Nombre *',
),
),
// NUMERO DE TELEFONO
body: TextFormField(
decoration: const InputDecoration(
border: UnderlineInputBorder(),
filled: true,
icon: Icon(Icons.phone),
hintText: 'Cual es tu numero',
labelText: 'Telefono *',
prefixText: '+51',
),
),
// CORREO
body: TextFormField(
decoration: const InputDecoration(
border: UnderlineInputBorder(),
filled: true,
icon: Icon(Icons.email),
hintText: 'Cual es tu correo e',
labelText: 'Correo',
),
),
// TEXT-AREA
body: TextFormField(
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: 'Cuentame acerca de ti',
helperText: 'Ingrese una breve historia',
labelText: 'Historia',
),
maxLines: 3,
),
// MONEDA
body: TextFormField(
keyboardType: TextInputType.number,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Salario',
prefixText: '\S/.',
suffixText: 'SOLES',
suffixStyle: TextStyle(color: Colors.green),
),
),
// CONTRASEÑA
BOTONES
RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
color: Colors.green,
textColor: Colors.white,
child: Text("presiona"),
onPressed: () {},
),
FlatButton(
child: Text("presiona"),
onPressed: () {},
),
IconButton(
icon: Icon(Icons.delete),
onPressed: () {},
),
OutlineButton(
onPressed: () {},
child: Text("boton"),
),
FloatingActionButton(
child: Icon(Icons.add),
backgroundColor: Colors.red,
onPressed: () {},
),
ROUTES
//home: Inicio(),
initialRoute: "/",
routes: {
"/": (BuildContext context) => Inicio(),
"/pagina2": (BuildContext context) => Pagina2(),
},
RECIBIR ARGUMENTOS DE RUTAS
class _Pagina2State extends State<Pagina2> {
@override
Widget build(BuildContext context) {
Pagina2Argumentos argumentos = ModalRoute.of(context).settings.arguments;
return Scaffold(
appBar: AppBar(),
body: Center(
child: Text(argumentos.nombre + " " + argumentos.apellido),
),
);
}
}
class Pagina2Argumentos {
String nombre;
String apellido;
Pagina2Argumentos({this.nombre, this.apellido});
}
EVENTOS O GestureDetector
Se utiliza para dar acciones cuando el usuario realice cualquier
cambio.
child: GestureDetector(
onTap: () {
print("Diste un click");
},
onLongPress: () {
print("Manteniste presionado");
},
child: Text(
"Hola",
style: TextStyle(fontSize: 50),
),
),
VALIDACION DE FORMULARIO
Se utiliza para validar campos de texto.
//CREANDO LAS VARIABLES DE RECEPCION
String txtNombre;
String txtApellido;
final formKey = GlobalKey<FormState>();
//INICIO DEL FORMULARIO
Form(
key: formKey,
child: Column(
children: [
TextFormField(
decoration: InputDecoration(labelText: "Nombre"),
onSaved: (value) {
this.txtNombre = value;
},
validator: (value) {
if (value.isEmpty) {
return "Campo vacio";
} else {
return null;
}
},
),
TextFormField(
decoration: InputDecoration(labelText: "Apellido"),
onSaved: (value) {
this.txtApellido = value;
},
validator: (value) {
if (value.isEmpty || value.trim() == "") {
return "Campo vacio";
} else {
return null;
}
},
),
],
),
),
//GUARDANDO LOS DATOS Y ENVIANDO A LA OTRA PAGINA
void _showPagina3() {
if (formKey.currentState.validate()) {
formKey.currentState.save();
Navigator.of(context).pushNamed(
"/pagina3",
arguments: ArgumentosPagina3(nombre: this.txtNombre, apellido: this.txtApellido),
);
}
}
TIPOS DE TECLADO
keyboardType: TextInputType.text,
keyboardType: TextInputType.number,
keyboardType: TextInputType.phone,
keyboardType: TextInputType.emailAddress,
DRAWER COMPLETO
class _InicioState extends State<Inicio> {
final _scaffKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return Scaffold(
//llave
key: _scaffKey,
drawer: _getDrawer(context),
floatingActionButton: FloatingActionButton(
child: IconButton(
icon: Icon(Icons.menu),
onPressed: () {
_scaffKey.currentState.openDrawer();
},
),
),
);
}
//contenido del drawer
Widget _getDrawer(BuildContext context) {
return Drawer(
child: ListView(
children: [
DrawerHeader(
decoration: BoxDecoration(color: Colors.black12),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Image.network(
"https://www.logaster.com/blog/wp-content/uploads/2018/05/Canva.png"),
Text("Uso de drawer")
],
),
),
ListTile(
title: Text("Inicio"),
leading: Icon(Icons.home),
onTap: () {
_showHome(context);
},
)
],
),
);
}
void _showHome(BuildContext context) {
Navigator.pop(context);
}
}
NOTIFICACION SNACKBAR
void _mostrarNotificacion() {
SnackBar snackBar = SnackBar(
content: Text("Elemento eliinado"),
backgroundColor: Colors.red[500],
action: SnackBarAction(
label: "Cancelar",
textColor: Colors.white,
onPressed: () {},
),
);
_scaffKey.currentState.showSnackBar(snackBar);
}
OTROS COMANDOS
//TEXTO SUBRAYADO
TextStyle(decoration: TextDecoration.underline)