'Package:flutter/material - Dart' 'Package:pageview - App/src/app - Dart'

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 93

F

import 'package:flutter/material.dart';
import 'package:pageview_app/src/app.dart';
void main() {
runApp(new MaterialApp(
home: App(),
));
}

import 'package:flutter/material.dart';
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Container(child: PageView.builder(
itemBuilder: (context, index) {
return Container(
color: index % 2 == 0 ? Colors.pink : Colors.blueAccent,
);
},
));
}
}
import 'package:flutter/material.dart';
import 'package:infinitelistview_app/src/app.dart';
void main() {
runApp(new MaterialApp(
home: App(),
));
}

import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';

class App extends StatefulWidget {


@override
_AppState createState() => new _AppState();
}

class _AppState extends State<App> {


final suggestions = <WordPair>[];
final saved = <WordPair>[];
ListTile buildRow(WordPair pair) {
final bool alreadySaved = saved.contains(pair);
return ListTile(
trailing: Icon(alreadySaved ? Icons.favorite : Icons.favorite_border,
color: Colors.redAccent),
title: Text(pair.asPascalCase),
onTap: () {
setState(() {
if (alreadySaved) {
saved.remove(pair);
} else {
saved.add(pair);
}
});
},
//subtitle: Text("precio: ${Random().nextInt(100)}"),
);
}

@override
Widget build(BuildContext context) {
void pushSaved() {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
final tiles = saved
.map((pair) => ListTile(
title: Text(pair.asCamelCase),
))
.toList();
return Scaffold(
appBar: AppBar(
title: Text("Guardado"),
),
body: ListView(
children: tiles,
),
);
}),
);
}

return new Scaffold(


appBar: AppBar(
title: Center(
child: Text("Lista Infinita"),
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.list),
onPressed: pushSaved,
)
],
),
body: ListView.builder(itemBuilder: (context, i) {
if (i.isOdd) return Divider();
if (i >= suggestions.length) {
suggestions.addAll(generateWordPairs().take(10));
}
return buildRow(suggestions[i]);
}),
);
}
}

dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.3
english_words: ^3.1.5
import 'package:drawer_app1/screens/battery.dart';
import 'package:drawer_app1/screens/home.dart';
import 'package:drawer_app1/screens/settings.dart';
import 'package:flutter/material.dart';

void main() {
runApp(new MaterialApp(home: Home(), routes: <String, WidgetBuilder>{
Settings.routeName: (BuildContext context) => Settings(),
Bettery.routeName: (BuildContext context) => Bettery(),
}));
}

import 'package:flutter/material.dart';

class Bettery extends StatelessWidget {


static const String routeName = "/bateria";
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Center(
child: Text("Bateria"),
),
),
body: Container(
child: Center(
child: Text("Pantalla de Bateria"),
),
),
);
}
}

import 'package:flutter/material.dart';

class Settings extends StatelessWidget {


static const String routeName = "/configuracion";
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Center(
child: Text("Configuraciones"),
),
),
body: Container(
child: Center(
child: Text("Pantalla de configuraciones"),
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:listview1/src/contact.dart';

void main() {
runApp(new MaterialApp(
home: Contact(),
));
}

import 'package:flutter/material.dart';

class ContactModel {
String email = "";
String name = "";
ContactModel({this.name, this.email});
}

import 'package:flutter/material.dart';
import 'package:listview1/src/model/contact_model.dart';

class ContacItem extends StatelessWidget {


final ContactModel contact;
ContacItem({this.contact});
@override
Widget build(BuildContext context) {
return new ListTile(
leading: CircleAvatar(
child: Text(contact.name[0]),
),
title: Text(contact.name),
subtitle: Text(contact.email),
);
}
}

import 'package:flutter/material.dart';
import 'package:listview1/src/screens/contact_item.dart';
import 'model/contact_model.dart';

class Contact extends StatelessWidget {


buildList() {
return <ContactModel>{
ContactModel(name: "Juan Cordova", email: "juanfercho4514@hotmail.com"),
ContactModel(
name: "Fernando Arevalo", email: "fernandoarevalo@hotmail.com"),
ContactModel(
name: "Rafaela Cordova", email: "rafaelacordova@hotmail.com"),
ContactModel(name: "Emili Idrovo", email: "emiliaidrovo@hotmail.com"),
ContactModel(name: "Ana Quirola", email: "anaquirola@hotmail.com"),
ContactModel(name: "Carolina Idrovo", email: "carolina@hotmail.com"),
ContactModel(name: "Veronica Cordova", email: "veronica@hotmail.com"),
ContactModel(name: "Eliana Arevalo", email: "elianaarevaloi@hotmail.com"),
ContactModel(name: "Galo Loja", email: "galoloja@hotmail.com"),
};
}

List<ContacItem> buildContactList() {
return buildList()
.map<ContacItem>((Contact) => ContacItem(contact: Contact))
.toList();
}

@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Center(
child: Text("Contactos"),
),
),
body: ListView(
children: buildContactList(),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:navigator_app1/src/app.dart';

void main() {
runApp(new MaterialApp(
home: App(),
));
}

import 'package:flutter/material.dart';

class Second extends StatelessWidget {


final String titulo;
Second({this.titulo});
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Center(
child: Text(titulo),
),
),
body: Center(
child: RaisedButton(
child: Text("Regresar"),
onPressed: () {
Navigator.pop(context);
},
),
),
);
}
}

import 'package:flutter/material.dart';
import 'package:navigator_app1/screens/second.dart';

class App extends StatefulWidget {


@override
_AppState createState() => new _AppState();
}

class _AppState extends State<App> {


@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Center(child: Text("Primera Pantalla ")),
),
body: Center(
child: RaisedButton(
child: Text("Mostrar pantalla"),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
Second(titulo: "Vamos muy bien amigos")));
},
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:stateful_app1/src/my_button.dart';

void main() {
runApp(MaterialApp(home: MyButton()));
}
import 'package:flutter/material.dart';

class MyButton extends StatefulWidget {


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

class _MyButtonState extends State<MyButton> {


String juanferStyle = "";
int index = 0;
List<String> collections = ['Juan', 'Fernando', 'Cordova', 'Arevalo'];

void onPressButton() {
setState(() {
juanferStyle = collections[index];
index = index < 3 ? index + 1 : 0;
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Center(
child: Text("SEGUNDO PROYECTO"),
),
backgroundColor: Colors.orangeAccent,
),
body: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
juanferStyle,
style: TextStyle(fontSize: 45),
),
Padding(padding: EdgeInsets.all(10.0)),
RaisedButton(
child: Text(
"Actualizar",
style: TextStyle(color: Colors.white),
),
color: Colors.blueAccent,
onPressed: onPressButton,
)
],
),
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:stateless_app1/src/app.dart';

void main() {
runApp(MaterialApp(
home: MyApp(),
));
}

class MyCard extends StatelessWidget {


final Widget title;
final Widget icon;

MyCard({this.title, this.icon});
@override
Widget build(BuildContext context) {
return Card(
child: Container(
padding: EdgeInsets.all(20.0),
child: Center(
child: Column(
children: <Widget>[this.title, this.icon],
),
),
),
);
}
}

import 'package:flutter/material.dart';

class MyCard extends StatelessWidget {


final Widget title;
final Widget icon;

MyCard({this.title, this.icon});
@override
Widget build(BuildContext context) {
return Card(
child: Container(
padding: EdgeInsets.all(20.0),
child: Center(
child: Column(
children: <Widget>[this.title, this.icon],
),
),
),
);
}
}

import 'package:flutter/material.dart';
import '../main.dart';

class MyApp extends StatelessWidget {


@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Center(
child: Text("Localizador de PERROS"),
),
),
body: Container(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.stretch, //OCUPA TODO EL TAMAÑO DEL DISPOSITIVO
children: <Widget>[
MyCard(
title: Text(
"Romulo Calle",
style: TextStyle(color: Colors.grey, fontSize: 30),
),
icon: Icon(
Icons.favorite,
color: Colors.redAccent,
size: 40.0,
),
),
MyCard(
title: Text(
"Perros perdidos",
style: TextStyle(color: Colors.grey, fontSize: 30),
),
icon: Icon(
Icons.adb,
color: Colors.blueAccent,
size: 40.0,
),
),
MyCard(
title: Text(
"Buscar a mi perro",
style: TextStyle(color: Colors.grey, fontSize: 30),
),
icon: Icon(
Icons.person_add,
color: Colors.greenAccent,
size: 40.0,
),
)
],
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:tabs_app1/src/tabs.dart';
void main() {
runApp(new MaterialApp(
home: MyTabsState(),
));
}

import 'package:flutter/material.dart';

class Contact extends StatelessWidget {


@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
Icon(
Icons.contacts,
size: 170.0,
color: Colors.grey,
),
Text("Tercer Tab")
],
),
);
}
}

import 'package:flutter/material.dart';

class Home extends StatelessWidget {


@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
Icon(
Icons.home,
size: 170.0,
color: Colors.blueAccent,
),
Text("Primer Tab")
],
),
);
}
}
import 'package:flutter/material.dart';

class Video extends StatelessWidget {


@override
Widget build(BuildContext context) {
return Container(
child: Column(
children: <Widget>[
Icon(
Icons.ondemand_video,
size: 170.0,
color: Colors.greenAccent,
),
Text("Segundo Tab")
],
),
);
}
}

import 'package:flutter/material.dart';
import 'package:tabs_app1/src/screens/contact.dart';
import 'package:tabs_app1/src/screens/home.dart';
import 'package:tabs_app1/src/screens/video.dart';

class MyTabsState extends StatefulWidget {


@override
_MyTabsStateState createState() => new _MyTabsStateState();
}

class _MyTabsStateState extends State<MyTabsState> {


@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Center(
child: Text(
"My TABS",
),
),
backgroundColor: Colors.redAccent,
bottom: TabBar(
tabs: <Widget>[
Tab(
icon: Icon(Icons.home),
),
Tab(
icon: Icon(Icons.ondemand_video),
),
Tab(
icon: Icon(Icons.contacts),
)
],
),
),
body: TabBarView(
children: <Widget>[Home(), Video(), Contact()],
),
));
}
}
import 'package:flutter/material.dart';
import 'package:tabsdesafio1/src/tabs.dart';

void main() {
runApp(new MaterialApp(
home: MyTabs(),
));
}

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:tabsdesafio1/src/screens/alarma.dart';
import 'package:tabsdesafio1/src/screens/relog.dart';
import 'package:tabsdesafio1/src/screens/vuelo.dart';

class MyTabs extends StatefulWidget {


@override
_MyTabsState createState() => new _MyTabsState();
}

class _MyTabsState extends State<MyTabs> {


@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Center(
child: Text("My TABS Desafio"),
),
backgroundColor: Colors.greenAccent,
),
body: TabBarView(
children: <Widget>[Alarma(), Relog(), Vuelo()],
),
bottomNavigationBar: Material(
color: Colors.greenAccent,
child: TabBar(
tabs: <Widget>[
Tab(
icon: Icon(Icons.alarm),
),
Tab(
icon: Icon(Icons.timer),
),
Tab(
icon: Icon(Icons.flight),
),
],
)),
),
);
}
}

import 'package:flutter/material.dart';

class Alarma extends StatelessWidget {


@override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.redAccent,
body: Container(
child: Center(
child: Column(
children: <Widget>[
Icon(
Icons.alarm,
size: 170.0,
color: Colors.greenAccent,
),
Text("Primer Tab")
],
mainAxisAlignment: MainAxisAlignment.center,
),
),
));
}
}

import 'package:flutter/material.dart';

class Relog extends StatelessWidget {


@override
Widget build(BuildContext context) {
return new Container(
child: Column(
children: <Widget>[
Icon(
Icons.timer,
size: 170.0,
color: Colors.greenAccent,
),
Text("Segundo Tab")
],
mainAxisAlignment: MainAxisAlignment.center,
),
color: Colors.redAccent,
);
}
}

import 'package:flutter/material.dart';

class Vuelo extends StatelessWidget {


@override
Widget build(BuildContext context) {
return new Container(
child: Column(
children: <Widget>[
Icon(
Icons.flight,
size: 170.0,
color: Colors.greenAccent,
),
Text("Tercer Tab")
],
mainAxisAlignment: MainAxisAlignment.center,
),
color: Colors.redAccent,
);
}
}
import 'package:flutter/material.dart';
import 'package:textdialogo_app1/src/dialogo.dart';

void main() {
runApp(MaterialApp(
home: MyDialogoField(),
));
}

import 'package:flutter/material.dart';

class MyDialogoField extends StatefulWidget {


@override
_MyDialogoFieldState createState() => new _MyDialogoFieldState();
}

enum DialogAction { yes, no }

class _MyDialogoFieldState extends State<MyDialogoField> {


String inputValue = "";
void alertResult(DialogAction action) {
print("Tu seleccion es : $action");
}

void onChanged(String value) {


setState(() {
inputValue = value;
});
}

void showAlert(String value) {


AlertDialog dialog = AlertDialog(
content: Text(value),
actions: <Widget>[
FlatButton(
child: Text("SI"),
onPressed: () {
alertResult(DialogAction.yes);
},
),
FlatButton(
child: Text("no"),
onPressed: () {
alertResult(DialogAction.no);
},
)
],
);
showDialog(
context: context,
builder: (BuildContext context) {
return dialog;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Center(
child: Text("Dialogo Field"),
),
),
body: Container(
child: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(hintText: "Ingrese el texto aqui!!"),
onChanged: onChanged,
),
RaisedButton(
child: Text(
"Ver Alerta",
style: TextStyle(color: Colors.white),
),
color: Colors.blueAccent,
onPressed: () {
showAlert(inputValue);
}),
],
),
),
);
}
}

Lo que se vería en el cli, cuando ingresamos yes o no en el diálogo.


import 'package:flutter/material.dart';
import 'package:textfiel_widget1/src/textfield.dart';

void main(List<String> args) {


runApp(MaterialApp(
home: MyTextField(),
));
}

import 'package:flutter/material.dart';

class MyTextField extends StatefulWidget {


@override
_MyTextFieldState createState() => new _MyTextFieldState();
}

class _MyTextFieldState extends State<MyTextField> {


String inputText = "";
final TextEditingController controller = TextEditingController();
void onSubMitted(String value) {
setState(() {
inputText = inputText + "\n" + value;
controller.text = "";
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Center(
child: Text("TextField Widget 1"),
),
),
body: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
TextField(
decoration: InputDecoration(
hintText: "Ingrese el texto aqui",
),
onSubmitted: onSubMitted,
controller: controller,
),
Text(inputText)
],
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:form_app/src/app.dart';

void main() {
runApp(new MaterialApp(
home: App(),
));
}

import 'package:flutter/material.dart';
import 'package:form_app/src/screens/login_screen.dart';

class App extends StatelessWidget {


@override
Widget build(BuildContext context) {
return new MaterialApp(
title: "Iniciar Seccion",
home: Scaffold(
body: LoginsScreen(),
),
);
}
}

import 'package:flutter/material.dart';
import 'package:form_app/src/mixins/validate_mixin.dart';

class LoginsScreen extends StatefulWidget {


@override
_LoginsScreenState createState() => new _LoginsScreenState();
}
class _LoginsScreenState extends State<LoginsScreen> with ValidateMixins {
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
return new Container(
margin:
EdgeInsets.all(20.0), //margenes del container en todas las esquinas
child: Form(
key: formKey,
child: Column(
children: <Widget>[
emailField(),
passwordField(),
Container(margin: EdgeInsets.only(top: 20.0)),
submitField()
],
)),
);
}
Widget emailField() {
return TextFormField(
keyboardType: TextInputType.emailAddress,
decoration:
InputDecoration(labelText: "Email", hintText: "you@example.com"),
validator: validateEmail,
onSaved: (String value) {
print("save " + value);
},
);
}

Widget passwordField() {
return TextFormField(
obscureText: true,
decoration:
InputDecoration(labelText: "Contraseña", hintText: "Password"),
validator: validatePassword,
onSaved: (String value) {
print("save " + value);
},
);
}

Widget submitField() {
return RaisedButton(
child: Text("Enviar"),
onPressed: () {
if (formKey.currentState.validate()) {
formKey.currentState.save();
}
//formKey.currentState.reset();
});
}
}

class ValidateMixins {
String validateEmail(String value) {
if (!value.contains("@")) return "Email invalido";
return null;
}

String validatePassword(String value) {


if (value.length < 6) return "Password invalido";
return null;
}
}
Al momento de presionar el botón “Enviar” tenemos el siguiente resultado:

dependencies:
flutter:
sdk: flutter

# The following adds the Cupertino Icons font to your application.


# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.3
provider: ^3.0.0
rxdart: ^0.22.6

dev_dependencies:
flutter_test:
sdk: flutter

import 'dart:async';

import 'package:login_bloc/src/bloc/validators.dart';
import 'package:rxdart/rxdart.dart';

class Bloc with Validators {


final _emailController =
BehaviorSubject<String>(); //Solo validara los tipos de datos String
final _passwordController = BehaviorSubject<String>();

Stream<String> get email => _emailController.stream.transform(validaEmail);


Stream<String> get password =>
_passwordController.stream.transform(validaPassword);
Stream<bool> get submitValid =>
Observable.combineLatest2(email, password, (a, b) => true);

Function(String) get changeEmail => _emailController.sink.add;


Function(String) get changePassword => _passwordController.sink.add;

submit() {
final valedEmail = _emailController.value;
final valedPass = _passwordController.value;
print('Email $valedEmail');
print('Password $valedPass');
}

//Con el siguiente codigo vamos a liberar recursos


dispose() {
_emailController.close();
_passwordController.close();
}
}

import 'dart:async';

class Validators {
final validaEmail =
StreamTransformer<String, String>.fromHandlers(handleData: (email, sink) {
if (email.contains('@')) {
sink.add(email);
} else {
sink.addError('Email invalido');
}
});
final validaPassword = StreamTransformer<String, String>.fromHandlers(
handleData: (password, sink) {
if (password.length > 5) {
sink.add(password);
} else {
sink.addError('Password invalido');
}
});
}

import 'package:flutter/material.dart';
import 'package:login_bloc/src/bloc/bloc.dart';
import 'package:provider/provider.dart';

class LoginScreen extends StatelessWidget {


@override
Widget build(BuildContext context) {
final bloc = Provider.of<Bloc>(context);
return new Container(
margin: EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
emailField(bloc),
passwordField(bloc),
Container(
margin: EdgeInsets.only(top: 25.0),
),
submitButton(bloc)
],
),
);
}

Widget emailField(Bloc bloc) {


return StreamBuilder(
stream: bloc.email,
builder: (context, snapshot) {
return TextField(
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
hintText: 'you@example.com',
labelText: 'Email',
errorText: snapshot.error),
onChanged: bloc.changeEmail);
},
);
}

Widget passwordField(Bloc bloc) {


return StreamBuilder(
stream: bloc.password,
builder: (context, snapshot) {
return TextField(
decoration: InputDecoration(
labelText: 'Contraseña',
hintText: 'Contraseña',
errorText: snapshot.error),
onChanged: bloc.changePassword);
},
);
}

Widget submitButton(Bloc bloc) {


return StreamBuilder(
stream: bloc.submitValid,
builder: (context, snapshot) {
return RaisedButton(
child: Text('Enviar'),
onPressed: snapshot.hasData
? bloc.submit
: null, //Deshabilotamos el boton si email y pass es incorrecto
);
},
);
}
}

import 'package:flutter/material.dart';
import 'package:login_bloc/src/screens/login_screen.dart';
import 'package:provider/provider.dart';
import 'package:login_bloc/src/bloc/bloc.dart';

class App extends StatelessWidget {


@override
Widget build(BuildContext context) {
return Provider<Bloc>(
builder: (context) => Bloc(),
dispose: (context, bloc) => bloc.dispose(),
child: new MaterialApp(
home: Scaffold(
body: LoginScreen(),
),
),
);
}
}

import 'package:flutter/material.dart';
import 'package:login_bloc/src/app.dart';

void main() {
runApp(new MaterialApp(
home: App(),
));
}
android/app
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}

def flutterRoot = localProperties.getProperty('flutter.sdk')


if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in
the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')


if (flutterVersionCode == null) {
flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')


if (flutterVersionName == null) {
flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'


apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
apply plugin: 'com.google.gms.google-services'

android {
compileSdkVersion 28

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}

lintOptions {
disable 'InvalidPackage'
}

defaultConfig {
// TODO: Specify your own unique Application ID
(https://developer.android.com/studio/build/application-id.html).
applicationId "com.juanfertech.panaschat"
minSdkVersion 16
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "Android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true
}

buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}

flutter {
source '../..'
}

dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.google.firebase:firebase-analytics:17.5.0'
implementation 'com.android.support:multidex:1.0.3'
}

android/
buildscript {
ext.kotlin_version = '1.3.50'
repositories {
google()
jcenter()
}

dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.3'
}
}
allprojects {
repositories {
google()
jcenter()
}
}

rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}

task clean(type: Delete) {


delete rootProject.buildDir
}

name: juanferchat_app
description: A new Flutter project.
# The following line prevents the package from being accidentally published to
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev

# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at
https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as
CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/
InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1
environment:
sdk: ">=2.7.0 <3.0.0"

dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.3
firebase_core: ^0.5.0
cloud_firestore: ^0.14.0+2
firebase_auth: ^0.18.0+1
modal_progress_hud: ^0.1.3

dev_dependencies:
flutter_test:
sdk: flutter

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:

# The following line ensures that the Material Icons font is


# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true

# To add assets to your application, add an assets section, like this:


assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
- images/
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.

# For details regarding adding assets from package dependencies, see


# https://flutter.dev/assets-and-images/#from-packages

# To add custom fonts to your application, add a fonts section here,


# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages

class Validation_Mixins {
String validateEmail(String value) {
if (!value.contains('@')) {
return "Email invalido";
return null;
}
}
String validatePassword(String value) {
if (value.length < 6) {
return "Password invalido";
return null;
}
}
}

class AuthenticationRequest {
bool success = false;
String errorMessage;
}

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:juanferchat_app/src/services/authentication.dart';
import 'package:juanferchat_app/src/services/message_service.dart';

class ChatScreen extends StatefulWidget {


static const String routeName = '/chat';
@override
_ChatScreenState createState() => new _ChatScreenState();
}

class _ChatScreenState extends State<ChatScreen> {


FirebaseAuth auth = FirebaseAuth.instance;
// ignore: deprecated_member_use
User loggedInUser;

TextEditingController _messageController = TextEditingController();


InputDecoration _messageTextFieldDecoration = InputDecoration(
contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
hintText: "Ingresar su mensaje aqui...",
border: InputBorder.none,
);
BoxDecoration _messageContainerDecoration = BoxDecoration(
border: Border(
top: BorderSide(color: Colors.lightBlueAccent, width: 2.0),
),
);
TextStyle _sendButtonStyle = TextStyle(
color: Colors.lightBlueAccent,
fontWeight: FontWeight.bold,
fontSize: 18.0);
@override
void initState() {
super.initState();
getCurrentUser();
_getMessages();
}

void getCurrentUser() async {


User user = await Authentication().getCurrentUser();
if (user != null) {
loggedInUser = user;
print(loggedInUser.email);
}
}

void _getMessages() async {


await for (var snapshot in MessageService().getMessageStream()) {
for (var message in snapshot.docs) {
print(message.data());
}
}
}

@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text('Chat Screen'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.power_settings_new),
onPressed: () {
Authentication().singOut();
Navigator.pop(context);
})
],
),
body: SafeArea(
child: Column(
children: <Widget>[
StreamBuilder<QuerySnapshot>(
stream: MessageService().getMessageStream(),
// ignore: missing_return
builder: (context, snapshot) {
if (snapshot.hasData) {
return Flexible(
child: ListView(
children: _getChatItem(snapshot.data.docs),
),
);
}
},
),
Container(
decoration: _messageContainerDecoration,
child: Row(
children: <Widget>[
Expanded(
child: TextField(
decoration: _messageTextFieldDecoration,
controller: _messageController,
),
),
FlatButton(
onPressed: () {
MessageService().save(
collectionName: "messages",
collectionValues: {
'value': _messageController.text,
'sender': loggedInUser.email
},
);
_messageController.clear();
},
child: Text("Enviar", style: _sendButtonStyle),
),
],
),
),
],
),
),
);
}

List<ChatItem> _getChatItem(dynamic messages) {


List<ChatItem> chatItems = [];
for (var message in messages) {
final messageValue = message.get('value');
final messageSender = message.get('sender');

chatItems.add(ChatItem(
message: messageValue,
sender: messageSender,
isLoggedInUser: messageSender == loggedInUser.email,
));
}
return chatItems;
}
}

class ChatItem extends StatelessWidget {


final String sender;
final String message;
final bool isLoggedInUser;
ChatItem({this.sender, this.message, this.isLoggedInUser});
@override
Widget build(BuildContext context) {
return new Container(
padding: EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment:
isLoggedInUser ? CrossAxisAlignment.end : CrossAxisAlignment.start,
children: <Widget>[
Text(
sender,
style: TextStyle(fontSize: 15.0, color: Colors.black54),
),
Material(
borderRadius: isLoggedInUser
? BorderRadius.only(
topLeft: Radius.circular(30.0),
bottomLeft: Radius.circular(30.0),
bottomRight: Radius.circular(30.0))
: BorderRadius.only(
topRight: Radius.circular(30.0),
bottomLeft: Radius.circular(30.0),
bottomRight: Radius.circular(30.0)),
elevation: 5.0,
color: isLoggedInUser
? Colors.lightBlueAccent
: Colors.lightGreenAccent,
child: Padding(
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
child: Text(
message,
style: TextStyle(fontSize: 16.0, color: Colors.white),
),
),
),
],
),
);
}
}

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:juanferchat_app/src/mixins/validation_mixins.dart';
import 'package:juanferchat_app/src/services/authentication.dart';
import 'package:juanferchat_app/src/widgets/app_button.dart';
import 'package:juanferchat_app/src/widgets/app_error_message.dart';
import 'package:juanferchat_app/src/widgets/app_icon.dart';
import 'package:juanferchat_app/src/widgets/app_textfield.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';

class LoginScreen extends StatefulWidget {


static const String routerName = '/login';

@override
_LoginScreenState createState() => new _LoginScreenState();
}

class _LoginScreenState extends State<LoginScreen> with Validation_Mixins {


TextEditingController _emailController = TextEditingController();
TextEditingController _passwordController = TextEditingController();
FocusNode _focusNode;
bool showSpinner = false;
bool _autoValidate = false;
final GlobalKey<FormState> _formkey = GlobalKey<FormState>();
String _errorMessage = "";
@override
void initState() {
// TODO: implement initState
super.initState();
_focusNode = FocusNode();
}

@override
void dispose() {
// TODO: implement dispose
super.dispose();
_focusNode.dispose();
_emailController.dispose();
_passwordController.dispose();
}

void setSpinnerStatus(bool status) {


setState(() {
showSpinner = status;
});
}

@override
Widget build(BuildContext context) {
return new Scaffold(
body: ModalProgressHUD(
inAsyncCall: showSpinner,
child: Form(
key: _formkey,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
AppIcon(),
SizedBox(height: 48.0),
_emailField(),
SizedBox(height: 8.0),
_passwordField(),
SizedBox(height: 23.0),
_showErrorMessage(),
_submitButton(),
],
),
),
),
),
);
}

Widget _emailField() {
return AppTextField(
inputText: 'Ingresar email',
validator: validateEmail,
focusNode: _focusNode,
autoVlidate: _autoValidate,
controller: _emailController,
onChanged: (value) {},
);
}

Widget _passwordField() {
return AppTextField(
controller: _passwordController,
autoVlidate: _autoValidate,
inputText: 'Ingresar contraseña',
validator: validatePassword,
obscureText: true,
onChanged: (value) {},
);
}

Widget _submitButton() {
return AppButton(
color: Colors.lightGreenAccent,
onPressed: () async {
if (_formkey.currentState.validate()) {
setSpinnerStatus(true);
var auth = await Authentication().logginUser(
email: _emailController.text, password: _passwordController.text);
if (auth.success) {
Navigator.pushNamed(context, '/chat');
FocusScope.of(context).requestFocus(_focusNode);
_emailController.text = "";
_passwordController.text = "";
} else {
setState(() {
_errorMessage = auth.errorMessage;
});
}
setSpinnerStatus(false);
} else {
setState(() => _autoValidate = true);
}
},
name: 'Ingresa Pana',
);
}

Widget _showErrorMessage() {
if (_errorMessage.length > 0 && _errorMessage != null) {
return ErrorMessage(errorMessage: _errorMessage);
} else {
return Container(
height: 0.0,
);
}
}
}

import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:juanferchat_app/src/mixins/validation_mixins.dart';
import 'package:juanferchat_app/src/services/authentication.dart';
import 'package:juanferchat_app/src/widgets/app_button.dart';
import 'package:juanferchat_app/src/widgets/app_error_message.dart';
import 'package:juanferchat_app/src/widgets/app_icon.dart';
import 'package:juanferchat_app/src/widgets/app_textfield.dart';
import 'package:firebase_auth/firebase_auth.dart';

class RegistrationScreen extends StatefulWidget {


static const String routerName = '/registrarse';
_RegistrationScreenState createState() => new _RegistrationScreenState();
}

class _RegistrationScreenState extends State<RegistrationScreen>


with Validation_Mixins {
final auth = FirebaseAuth.instance;

FocusNode _focusNode;
TextEditingController _emailController;
TextEditingController _passwordController;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
bool _autoValidate = false;
String _errorMessage = "";

@override
void initState() {
// TODO: implement initState
super.initState();
_focusNode = FocusNode();
_emailController = TextEditingController();
_passwordController = TextEditingController();
}

@override
void dispose() {
// TODO: implement dispose
super.dispose();
_focusNode.dispose();
_emailController.dispose();
_passwordController.dispose();
}

@override
Widget build(BuildContext context) {
return new Scaffold(
body: Form(
key: _formKey,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
AppIcon(),
SizedBox(
height: 48.0,
),
_emailField(),
SizedBox(
height: 8.0,
),
_passwordField(),
SizedBox(
height: 24.0,
),
_showErrorMessage(),
_submitButton(),
],
),
),
),
);
}

Widget _emailField() {
return AppTextField(
inputText: 'Ingresar email',
autoVlidate: _autoValidate,
validator: validateEmail,
focusNode: _focusNode,
controller: _emailController,
onChanged: (value) {},
);
}

Widget _passwordField() {
return AppTextField(
inputText: 'Ingresar Contraseña',
autoVlidate: _autoValidate,
validator: validatePassword,
controller: _passwordController,
obscureText: true,
onChanged: (value) {},
);
}

Widget _submitButton() {
return AppButton(
color: Colors.lightBlueAccent,
onPressed: () async {
if (_formKey.currentState.validate()) {
var auth = await Authentication().createUser(
email: _emailController.text, password: _passwordController.text);
if (auth.success) {
Navigator.pushNamed(context, '/chat');
_emailController.text = "";
_passwordController.text = "";
FocusScope.of(context).requestFocus(_focusNode);
} else {
setState(() {
_errorMessage = auth.errorMessage;
});
}
} else {
setState(() => _autoValidate = true);
}
},
name: 'Registrarse',
);
}

Widget _showErrorMessage() {
if (_errorMessage.length > 0 && _errorMessage != null) {
return ErrorMessage(errorMessage: _errorMessage);
} else {
return Container(
height: 0.0,
);
}
}
}

import 'package:flutter/material.dart';
import 'package:juanferchat_app/src/widgets/app_button.dart';
import 'package:juanferchat_app/src/widgets/app_icon.dart';

class WelcomeScreen extends StatefulWidget {


static const String routeName = '';
@override
_WelcomeScreenState createState() => new _WelcomeScreenState();
}

class _WelcomeScreenState extends State<WelcomeScreen> {


@override
Widget build(BuildContext context) {
return new Scaffold(
body: Container(
padding: EdgeInsets.symmetric(horizontal: 25.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
AppIcon(),
SizedBox(
height: 48.0,
),
AppButton(
color: Colors.lightGreenAccent,
onPressed: () {
Navigator.pushNamed(context, '/login');
},
name: 'Ingresar',
),
AppButton(
color: Colors.lightBlueAccent,
onPressed: () {
Navigator.pushNamed(context, '/registrarse');
},
name: 'Registrarse',
),
],
)));
}
}

import 'package:firebase_auth/firebase_auth.dart';
import 'package:juanferchat_app/src/model/auth_request.dart';

class Authentication {
FirebaseAuth _auth = FirebaseAuth.instance;

Future<AuthenticationRequest> createUser(
{String email = '', String password = ''}) async {
AuthenticationRequest authRequest = AuthenticationRequest();

try {
var user = await _auth.createUserWithEmailAndPassword(
email: email, password: password);
if (user != null) {
authRequest.success = true;
}
} catch (e) {
_mapErrorMessage(authRequest, e.code);
}
return authRequest;
}

Future<User> getCurrentUser() async {


try {
return await _auth.currentUser;
} catch (e) {
print(e);
}
return null;
}
Future<AuthenticationRequest> logginUser(
{String email = '', String password = ''}) async {
AuthenticationRequest authRequest = AuthenticationRequest();
try {
var user = await _auth.signInWithEmailAndPassword(
email: email, password: password);
if (user != null) {
authRequest.success = true;
}
} catch (e) {
_mapErrorMessage(authRequest, e.code);
}
return authRequest;
}

Future<void> singOut({String email = '', String password = ''}) async {


try {
return await _auth.signOut();
} catch (e) {
print(e);
}
return null;
}

void _mapErrorMessage(AuthenticationRequest authRequest, String code) {


switch (code) {
case 'user-not-found':
authRequest.errorMessage = "Usuario no encontrado";
break;
case 'wrong-password':
authRequest.errorMessage = "Contraseña invalida";
break;
case 'network-request-failed':
authRequest.errorMessage = "Error de red";
break;
case 'email-already-in-use':
authRequest.errorMessage = "El usuario ya esta registrado";
break;

default:
authRequest.errorMessage = code;
}
}
}

import 'package:cloud_firestore/cloud_firestore.dart';

class MessageService {
FirebaseFirestore _fireStore = FirebaseFirestore.instance;
void save({String collectionName, Map<String, dynamic> collectionValues}) {
_fireStore.collection(collectionName).add(collectionValues);
}

Future<QuerySnapshot> getMessage() async {


return await _fireStore.collection("messages").get();
}

Stream<QuerySnapshot> getMessageStream() {
return _fireStore.collection('messages').snapshots();
}
}

import 'package:flutter/material.dart';

class AppButton extends StatelessWidget {


final MaterialAccentColor color;
final VoidCallback onPressed;
final String name;

const AppButton({this.color, this.onPressed, this.name});


@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.symmetric(vertical: 16.0),
child: Material(
color: color,
borderRadius: BorderRadius.circular(30.0),
elevation: 9.0,
child: SizedBox(
height: 43.0,
child: FlatButton(
child: Text(name),
onPressed: onPressed,
),
)),
);
}
}

import 'package:flutter/material.dart';

class ErrorMessage extends StatelessWidget {


final String errorMessage;
ErrorMessage({this.errorMessage});

@override
Widget build(BuildContext context) {
return new Text(
errorMessage,
style: TextStyle(
fontSize: 13.0,
color: Colors.redAccent,
height: 1.0,
fontWeight: FontWeight.w300),
);
}
}

import 'package:flutter/material.dart';

class AppIcon extends StatelessWidget {


@override
Widget build(BuildContext context) {
return new Row(
children: <Widget>[
Image.asset('images/logo.png'),
Padding(padding: EdgeInsets.all(3.0)),
Text(
'Solos Panas',
style: TextStyle(fontSize: 45.0, fontWeight: FontWeight.w700),
),
],
);
}
}

import 'package:flutter/material.dart';

class AppTextField extends StatelessWidget {


final String inputText;
final ValueChanged<String> onChanged;
final bool obscureText;
final TextEditingController controller;
final FocusNode focusNode;
final FormFieldValidator<String> validator;
final bool autoVlidate;
const AppTextField(
{this.inputText,
this.onChanged,
this.obscureText,
this.controller,
this.focusNode,
this.validator,
this.autoVlidate});

@override
Widget build(BuildContext context) {
return TextFormField(
autovalidate: autoVlidate,
validator: validator,
focusNode: focusNode,
controller: controller,
decoration: InputDecoration(
contentPadding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0),
hintText: inputText,
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(32.0)),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(32.0)),
borderSide: BorderSide(color: Colors.lightGreenAccent, width: 2.0),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(32.0)),
borderSide: BorderSide(color: Colors.greenAccent, width: 2.0),
),
),
onChanged: onChanged,
textAlign: TextAlign.center,
obscureText: obscureText == null ? false : obscureText,
);
}
}

import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:juanferchat_app/src/screens/chat_screen.dart';
import 'package:juanferchat_app/src/screens/login_screen.dart';
import 'package:juanferchat_app/src/screens/registration_screen.dart';
import 'package:juanferchat_app/src/screens/welcome_screen.dart';

void main() async {


WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(
new MaterialApp(
home: WelcomeScreen(),
theme: ThemeData(
textTheme: TextTheme(
bodyText2: TextStyle(color: Colors.black45),
),
),
initialRoute: WelcomeScreen.routeName,
routes: <String, WidgetBuilder>{
LoginScreen.routerName: (BuildContext context) => LoginScreen(),
WelcomeScreen.routeName: (BuildContext context) => WelcomeScreen(),
RegistrationScreen.routerName: (BuildContext context) =>
RegistrationScreen(),
ChatScreen.routeName: (BuildContext context) => ChatScreen(),
},
),
);
}

FIREBASE

https://iconos8.es/icons/set/CHAT
CREAMOS LA BASE DE DATOS
name: movie_app
description: A new Flutter project.

# The following line prevents the package from being accidentally published to
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev

# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at
https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as
CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/
InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1

environment:
sdk: ">=2.7.0 <3.0.0"

dependencies:
http: ^0.12.2
sqflite:
path_provider: ^0.4.1
flutter:
sdk: flutter

# The following adds the Cupertino Icons font to your application.


# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.3

dev_dependencies:
flutter_test:
sdk: flutter

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

# The following section is specific to Flutter.


flutter:

# The following line ensures that the Material Icons font is


# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true

# To add assets to your application, add an assets section, like this:


assets:
- assets/logo.png
# - images/a_dot_ham.jpeg

# An image asset can refer to one or more resolution-specific "variants", see


# https://flutter.dev/assets-and-images/#resolution-aware.

# For details regarding adding assets from package dependencies, see


# https://flutter.dev/assets-and-images/#from-packages

# To add custom fonts to your application, add a fonts section here,


# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages

final String API_KEY = "0d908d9c602d1802ddf1b082f769b20f";

import 'dart:async';
import 'package:movie_app/model/Cast.dart';
import 'package:movie_app/model/Media.dart';
import 'package:movie_app/resources/api_provider.dart';
import 'package:movie_app/resources/repository.dart';

//herencia
abstract class MediaProvider {
Repository _repository = Repository.get();
Future<List<Media>> fetchMedia(String category);
Future<List<Cast>> fetchCast(int mediaId);
}

class MovieProvider extends MediaProvider {


ApiProvider _client = ApiProvider.get();
@override
Future<List<Media>> fetchMedia(String category) {
return _client.fetchMovies(category: category);
}

@override
Future<List<Cast>> fetchCast(int mediaId) {
return _repository.fetchCastMovies(mediaId);
}
}

class ShowProvider extends MediaProvider {


ApiProvider _client = ApiProvider.get();
@override
Future<List<Media>> fetchMedia(String category) {
return _client.fetchShow(category: category);
}

@override
Future<List<Cast>> fetchCast(int mediaId) {
return _repository.fetchCastShows(mediaId);
}
}

enum MediaType { movie, show }

final String _imageUrlMedium = "https://image.tmdb.org/t/p/w300";


final String _imageUrlLarge = "https://image.tmdb.org/t/p/w500";
String getMediumPictureUrl(String path) => _imageUrlMedium + path;
String getLargePictureUrl(String path) => _imageUrlLarge + path;
Map<int, String> _genreMap = {
28: 'Acción',
12: 'Aventura',
16: 'Animación',
35: 'Comedia',
80: 'Crimen',
99: 'Documental',
18: 'Drama',
10751: 'Familia',
14: 'Fantasía',
36: 'Historia',
27: 'Terror',
10402: 'Música',
9648: 'Misterio',
10749: 'Romance',
878: 'Ciencia ficción',
10770: 'película de la televisión',
53: 'Suspenso',
10752: 'Guerra',
37: 'Oeste',
10759: 'Acción & Aventura',
10762: "Infantil",
10763: 'Noticias',
10764: 'Realities',
10765: 'Sci-Fi & Fantasia',
10766: 'Serial',
10767: 'Conversación',
10768: 'Guerra & Politica',
};

List<String> genresToList(List<dynamic> genreIds) =>


genreIds.map((id) => _genreMap[id]).toList();

String getGenreValues(List<dynamic> genreIds) {


StringBuffer buffer = new StringBuffer();
buffer.writeAll(genresToList(genreIds), ", ");
return buffer.toString();
}
import 'package:movie_app/common/MediaProvider.dart';
import 'package:movie_app/common/Util.dart';

class Cast {
int id;
String name;
String profilePath;
int mediaId;
String getCastUrl() => getMediumPictureUrl(profilePath);

factory Cast(Map jsonMap, MediaType mediaType, int mediaId) {


try {
return new Cast.deserializa(jsonMap, mediaType, mediaId);
} catch (ex) {
throw ex;
}
}
Cast.deserializa(Map jsonMap, MediaType mediaType, int mediaId)
: id = jsonMap["id"].toInt(),
name = jsonMap["name"],
profilePath = jsonMap["profile_path"] ?? "logo.png",
mediaId = mediaId;

Cast.fromDb(Map<String, dynamic> parsedJson)


: id = parsedJson["id"].toInt(),
name = parsedJson["name"],
profilePath = parsedJson["profile_path"],
mediaId = parsedJson["media_Id"].toInt();

Map<String, dynamic> toMap() {


return <String, dynamic>{
"id": id,
"name": name,
"media_Id": mediaId,
"profile_path": profilePath
};
}
}

import 'package:movie_app/common/Util.dart';
import 'package:movie_app/common/MediaProvider.dart';

class Media {
int id;
double voteAverage;
String title;
String posterPath;
String backdropPath;
String overview;
String releaseDate;
List<dynamic> genreIds;
String getPosterUrl() => getMediumPictureUrl(posterPath);
String getBackDropUrl() => getLargePictureUrl(backdropPath);
String getGenres() => getGenreValues(genreIds);

int getReleaseYear() {
if (releaseDate == null || releaseDate == "") {
return 0;
}
return DateTime.parse(releaseDate).year;
}

factory Media(Map jsonMap, MediaType mediaType) {


try {
return new Media.deserializa(jsonMap, mediaType);
} catch (ex) {
throw ex;
}
}
Media.deserializa(Map json, MediaType mediaType)
: id = json["id"].toInt(),
voteAverage = json["vote_average"].toDouble(),
title = json[mediaType == MediaType.movie ? "title" : "name"],
posterPath = json["poster_path"] ?? "",
backdropPath = json["backdrop_path"] ?? "",
overview = json["overview"],
releaseDate = json[
mediaType == MediaType.movie ? "release_date" : "first_air_date"],
genreIds = json["genre_ids"].toList();
}

import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:movie_app/common/Constants.dart';
import 'package:movie_app/model/Media.dart';
import 'package:movie_app/common/MediaProvider.dart';
import 'package:movie_app/model/Cast.dart';

class ApiProvider {
static final _apiProvider = new ApiProvider();
final String _baseUrl = "api.themoviedb.org";
final String _language = "es-ES";

static ApiProvider get() {


return _apiProvider;
}

Future<dynamic> getJson(Uri uri) async {


http.Response response = await http.get(uri);
return json.decode(response.body);
}

Future<List<Media>> fetchMovies({String category: "populares"}) async {


var uri = new Uri.https(_baseUrl, "3/movie/$category",
{'api_key': API_KEY, 'page': "1", 'language': _language});
return getJson(uri).then(((data) => data['results']
.map<Media>((item) => new Media(item, MediaType.movie))
.toList()));
}

Future<List<Media>> fetchShow({String category: "populares"}) async {


var uri = new Uri.https(_baseUrl, "3/tv/$category",
{'api_key': API_KEY, 'page': "1", 'language': _language});
return getJson(uri).then(((data) => data['results']
.map<Media>((item) => new Media(item, MediaType.show))
.toList()));
}

Future<List<Cast>> fetchCreditMovies(int mediaId) async {


print('${mediaId.toString()} Lectura de tmdb para movies');
var uri = new Uri.https(_baseUrl, "3/movie/$mediaId/credits",
{'api_key': API_KEY, 'page': "1", 'language': _language});
return getJson(uri).then(((data) => data['cast']
.map<Cast>((item) => new Cast(item, MediaType.movie, mediaId))
.toList()));
}

Future<List<Cast>> fetchCreditShow(int mediaId) async {


print('${mediaId.toString()} Lectura de tmdb para shows');
var uri = new Uri.https(_baseUrl, "3/tv/$mediaId/credits",
{'api_key': API_KEY, 'page': "1", 'language': _language});
return getJson(uri).then(((data) => data['cast']
.map<Cast>((item) => new Cast(item, MediaType.show, mediaId))
.toList()));
}
}

import 'package:movie_app/model/Cast.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart';
import 'dart:io';

class DBProvider {
static final DBProvider _dbProvider = new DBProvider();
Database db; //instancia para insertar en la base de datos
DBProvider() {
init();
}
static DBProvider get() {
return _dbProvider;
}

void init() async {


Directory documentDirectory =
await getApplicationDocumentsDirectory(); //retornamos un directorio
final path = join(documentDirectory.path, "Cast4.db");
db = await openDatabase(
path,
version: 1, //manejamos las versiones de nuestras bases de datos
onCreate: (Database newDB, int version) {
newDB.execute("""
CREATE TABLE Casts(
id INTEGER PRIMARY KEY,
name TEXT,
profile_path TEXT,
media_Id INTEGER
)
""");
}, //creamos las estructura principal de la base de datos
);
}

Future<List<Cast>> fetchCast(int mediaId) async {


print('${mediaId.toString()} Lectura de Base de datos local');
//maps:
var maps = await db.query("Casts",
columns: null,
where:
"media_Id = ?", //? envia como argumento el nombre de la propiedad
whereArgs: [mediaId]);
if (maps.length > 0) {
return maps.map<Cast>((item) => new Cast.fromDb(item)).toList();
}
return null;
}

void addCast(Cast cast) {


print('${cast.mediaId.toString()} Insertar en Base de datos local');
db.insert(
"Casts",
cast.toMap(),
conflictAlgorithm: ConflictAlgorithm.fail,
);
}
}

import 'package:movie_app/model/Cast.dart';
import 'package:movie_app/resources/api_provider.dart';
import 'package:movie_app/resources/db_provider.dart';

class Repository {
static final Repository _repository = new Repository();
ApiProvider _apiProvider = ApiProvider.get();
DBProvider _dbProvider = DBProvider.get();
static Repository get() {
return _repository;
}

Future<List<Cast>> fetchCastMovies(int mediaId) async {


List<Cast> list = await _dbProvider.fetchCast(mediaId);
if (list != null) {
return list;
}
list = await _apiProvider.fetchCreditMovies(mediaId);
list.forEach((element) => _dbProvider.addCast(element));
return list;
}

Future<List<Cast>> fetchCastShows(int mediaId) async {


List<Cast> list = await _dbProvider.fetchCast(mediaId);
if (list != null) {
return list;
}
list = await _apiProvider.fetchCreditShow(mediaId);
list.forEach((element) => _dbProvider.addCast(element));
return list;
}
}

import 'package:movie_app/model/Cast.dart';

abstract class ResourceProvider {


Future<List<Cast>> fetchCasts(int mediaId);
}

import 'package:flutter/material.dart';
import 'package:movie_app/common/MediaProvider.dart';
import 'package:movie_app/model/Cast.dart';

class CastController extends StatefulWidget {


final MediaProvider provider;
final int mediaId;
CastController(this.provider, this.mediaId);
@override
_CastControllerState createState() => new _CastControllerState();
}

class _CastControllerState extends State<CastController> {


@override
void initState() {
super.initState();
loadCasts();
}

final List<Cast> _casts = new List<Cast>();


void loadCasts() async {
final results = await widget.provider.fetchCast(widget.mediaId);
setState(() {
_casts.addAll(results);
});
}

Widget _builderCasts(BuildContext ctx, int index) {


final cast = _casts[index];
return Padding(
padding: const EdgeInsets.only(right: 16.0),
child: new Column(
children: <Widget>[
CircleAvatar(
backgroundImage: new NetworkImage(cast.getCastUrl()),
radius: 40.0,
),
Padding(
padding: const EdgeInsets.only(top: 12.0),
child: Text(cast.name),
)
],
),
);
}
@override
Widget build(BuildContext context) {
return new Column(
children: <Widget>[
SizedBox.fromSize(
size: const Size.fromHeight(180.0),
child: ListView.builder(
itemCount: _casts.length,
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.only(top: 20.0, left: 20.0),
itemBuilder: _builderCasts,
),
)
],
);
}
}

import 'package:flutter/material.dart';
import 'package:movie_app/media_list.dart';
import 'package:movie_app/common/MediaProvider.dart';

class Home extends StatefulWidget {


@override
_HomeState createState() => new _HomeState();
}

class _HomeState extends State<Home> {


@override
void initState() {
// TODO: implement initState
_pageController = new PageController();
super.initState();
}

@override
void dispose() {
_pageController.dispose();
super.dispose();
}

final MediaProvider movieProvider = new MovieProvider();


final MediaProvider showProvider = new ShowProvider();
PageController _pageController;
int _page = 0;
MediaType mediaType = MediaType.movie;
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text("Cartelera recomendada"),
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.search, color: Colors.white),
onPressed: () {})
],
),
drawer: new Drawer(
child: new ListView(
children: <Widget>[
new DrawerHeader(child: new Material()),
new ListTile(
title: new Text("Peliculas"),
selected: mediaType == MediaType.movie,
trailing: new Icon(Icons.local_movies),
onTap: () {
_changeMediaType(MediaType.movie);
Navigator.of(context).pop();
},
),
new Divider(
height: 5.0,
),
new ListTile(
title: new Text("Television"),
selected: mediaType == MediaType.show,
trailing: new Icon(Icons.live_tv),
onTap: () {
_changeMediaType(MediaType.show);
Navigator.of(context).pop();
},
),
new Divider(
height: 5.0,
),
new ListTile(
title: new Text("Cerrar"),
trailing: new Icon(Icons.close),
onTap: () => Navigator.of(context).pop(),
),
],
)),
body: new PageView(
children: _getMediaList(),
controller: _pageController,
onPageChanged: (int index) {
setState(() {
_page = index;
});
},
),
bottomNavigationBar: new BottomNavigationBar(
items: _getFooterItems(),
onTap: _navigationTapped,
currentIndex: _page,
),
);
}

List<BottomNavigationBarItem> _getFooterItems() {
return mediaType == MediaType.show
? [
new BottomNavigationBarItem(
icon: new Icon(Icons.thumb_up),
// ignore: deprecated_member_use
title: new Text("Polulares"),
),
new BottomNavigationBarItem(
icon: new Icon(Icons.update),
// ignore: deprecated_member_use
title: new Text("En el aire"),
),
new BottomNavigationBarItem(
icon: new Icon(Icons.star),
// ignore: deprecated_member_use
title: new Text("Mejor valoradas"),
)
]
: [
new BottomNavigationBarItem(
icon: new Icon(Icons.thumb_up),
// ignore: deprecated_member_use
title: new Text("Polulares"),
),
new BottomNavigationBarItem(
icon: new Icon(Icons.update),
// ignore: deprecated_member_use
title: new Text("Proximamente"),
),
new BottomNavigationBarItem(
icon: new Icon(Icons.star),
// ignore: deprecated_member_use
title: new Text("Mejor valoradas"),
)
];
}
void _changeMediaType(MediaType type) {
if (mediaType != type) {
setState(() {
mediaType = type;
});
}
}

List<Widget> _getMediaList() {
return (mediaType == MediaType.movie)
? <Widget>[
new MediaList(movieProvider, "popular"),
new MediaList(movieProvider, "upcoming"),
new MediaList(movieProvider, "top_rated"),
]
: <Widget>[
new MediaList(showProvider, "popular"),
new MediaList(showProvider, "on_the_air"),
new MediaList(showProvider, "top_rated"),
];
}

void _navigationTapped(int page) {


_pageController.animateToPage(page,
duration: const Duration(microseconds: 300), curve: Curves.ease);
}
}

import 'package:flutter/material.dart';

import 'home.dart';

void main() {
runApp(new MaterialApp(
home: Home(),
theme: new ThemeData.dark(),
));
}

import 'package:flutter/material.dart';
import 'package:movie_app/common/MediaProvider.dart';
import 'cast_scroller.dart';
import 'model/Media.dart';
import 'dart:ui' as ui;
class MediaDetail extends StatelessWidget {
final Media media;
final MediaProvider provider;
MediaDetail(this.media, this.provider);
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new Stack(
fit: StackFit.expand,
children: <Widget>[
new Image.network(
media.getBackDropUrl(),
fit: BoxFit.cover,
),
//para el degradado de la foto
new BackdropFilter(
filter: new ui.ImageFilter.blur(sigmaX: 5.0, sigmaY: 5.0),
child: new Container(
color: Colors.black.withOpacity(0.5),
),
),
new SingleChildScrollView(
child: new Container(
margin: const EdgeInsets.all(20.0),
child: new Column(
children: <Widget>[
new Container(
alignment: Alignment.center,
child: new Container(
width: 390.0,
height: 390.0,
),
decoration: new BoxDecoration(
borderRadius: new BorderRadius.circular(10.0),
image: new DecorationImage(
image: new NetworkImage(
media.getPosterUrl(),
),
),
boxShadow: [
new BoxShadow(
color: Colors.black,
blurRadius: 20.0,
offset: new Offset(0.0, 10.0))
]),
),
SizedBox(height: 20.0),
new Container(
margin: const EdgeInsets.symmetric(
vertical: 5.0,
),
child: new Row(
children: <Widget>[
new Expanded(
child: new Text(
media.title,
overflow: TextOverflow.fade,
maxLines: 1,
style: new TextStyle(
color: Colors.white,
fontSize: 25.0,
fontFamily: 'Arvo'),
),
),
new Text(
'${media.voteAverage.toString()}/10',
style: new TextStyle(
color: Colors.white,
fontSize: 15.0,
fontFamily: 'Arvo'),
)
],
),
),
new Column(
children: <Widget>[
new Text(
media.overview,
overflow: TextOverflow.ellipsis,
maxLines: media.overview.length,
style: TextStyle(
color: Colors.white,
fontSize: 13.0,
fontFamily: 'Arvo'),
)
],
),
CastController(provider, media.id)
],
),
),
),
],
),
);
}
}
import 'package:flutter/material.dart';
import 'model/Media.dart';

class MediaListItem extends StatelessWidget {


final Media media;
MediaListItem(this.media);
@override
Widget build(BuildContext context) {
return new Card(
child: new Column(
children: <Widget>[
Container(
child: new Stack(
children: <Widget>[
new FadeInImage.assetNetwork(
placeholder: "assets/logo.png",
image: media.getBackDropUrl(),
fit: BoxFit.cover,
width: double.infinity,
height: 200.0,
fadeInDuration: new Duration(milliseconds: 40),
),
new Positioned(
left: 0.0,
bottom: 0.0,
right: 0.0,
child: new Container(
decoration: new BoxDecoration(
color: Colors.grey[900].withOpacity(0.5),
),
constraints: new BoxConstraints.expand(height: 55.0),
),
),
new Positioned(
left: 10.0,
bottom: 10.0,
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Container(
width: 250.0,
child: new Text(
media.title,
style: new TextStyle(
fontWeight: FontWeight.bold, color: Colors.white),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
new Container(
width: 250.0,
padding: const EdgeInsets.only(top: 4.0),
child: new Text(
media.getGenres(),
style: new TextStyle(color: Colors.white),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
new Positioned(
right: 5.0,
bottom: 10.0,
child: Column(
children: <Widget>[
new Row(
children: <Widget>[
new Text(media.voteAverage.toString()),
new Container(
width: 4.0,
),
new Icon(
Icons.star,
color: Colors.white,
size: 16.0,
)
],
),
new Container(
height: 4.0,
),
new Row(
children: <Widget>[
new Text(media.getReleaseYear().toString()),
new Container(
width: 4.0,
),
new Icon(
Icons.date_range,
color: Colors.white,
size: 16.0,
)
],
)
],
),
),
],
),
),
],
),
);
}
}

import 'package:flutter/material.dart';
import 'package:movie_app/model/Media.dart';
import 'package:movie_app/media_list_item.dart';
import 'package:movie_app/common/MediaProvider.dart';
import 'package:movie_app/MEDIA_DATAIL.DART';

class MediaList extends StatefulWidget {


final MediaProvider provider;
String category;
MediaList(this.provider, this.category);
@override
_MediaListState createState() => new _MediaListState();
}

class _MediaListState extends State<MediaList> {


List<Media> _media = new List();

@override
void initState() {
// TODO: implement initState
super.initState();
loadMovies();
}

@override
void didUpdateWidget(MediaList oldWidget) {
if (oldWidget.provider.runtimeType != widget.provider.runtimeType) {
_media = new List();
loadMovies();
}
super.didUpdateWidget(oldWidget);
}

void loadMovies() async {


var media = await widget.provider.fetchMedia(widget.category);
setState(() {
_media.addAll(media);
});
}

@override
Widget build(BuildContext context) {
return new Container(
child: new ListView.builder(
itemCount: _media.length,
itemBuilder: (BuildContext context, int index) {
return new FlatButton(
child: new MediaListItem(_media[index]),
padding: const EdgeInsets.all(1),
onPressed: () {
Navigator.push(context,
new MaterialPageRoute(builder: (context) {
return new MediaDetail(_media[index], widget.provider);
}));
});
}),
);
}
}

coursera.org/learn/technical-support-fundamentals/quiz/EV1vi/the-modern-computer?
redirectToCover=true
https://www.themoviedb.org/settings/api

You might also like