Skip to content

Instantly share code, notes, and snippets.

@roipeker
Last active August 31, 2020 00:39
Show Gist options
  • Save roipeker/bb329c8dd839facc99db7136777cd1e5 to your computer and use it in GitHub Desktop.
Save roipeker/bb329c8dd839facc99db7136777cd1e5 to your computer and use it in GitHub Desktop.
Demo Jornada de partidos con GetX ( roi-getx-partidos.surge.sh )
/// roipeker 2020
///
/// LIVE DEMO: https://roi-getx-partidos.surge.sh/
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class AppSamplePartidos extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
debugShowCheckedModeBanner: false,
home: _HomePartidos(),
initialBinding: BindingsBuilder(() {
final api = Get.put(Api(), permanent: true);
Get.put(HomePartidosController(api));
}),
);
}
}
/// model
class Temporada {
List<PartidoModel> jornada;
@override
String toString() => 'Temporada{jornada: $jornada}';
Temporada({this.jornada});
factory Temporada.fromJson(Map<String, dynamic> json) => Temporada(
// cambia esto para que lea los Keys si queres matenerlo asi.
jornada: List<PartidoModel>.from(json["Jornada 38"].map(
(x) => PartidoModel.fromJson(x),
)),
);
}
class PartidoModel {
PartidoModel({
this.awayGoals,
this.escudoAway,
this.escudoHome,
this.homeGoals,
this.id,
this.name,
this.scoreAway,
this.scoreHome,
this.teamAway,
this.teamHome,
});
List<String> awayGoals;
String escudoAway;
String escudoHome;
List<String> homeGoals;
String id;
String name;
String scoreAway;
String scoreHome;
String teamAway;
String teamHome;
factory PartidoModel.fromJson(Map<String, dynamic> json) => PartidoModel(
awayGoals: List<String>.from(json["away_goals"].map((x) => x)),
escudoAway: json["escudo_away"],
escudoHome: json["escudo_home"],
homeGoals: List<String>.from(json["home_goals"].map((x) => x)),
id: json["id"],
name: json["name"],
scoreAway: json["score_away"],
scoreHome: json["score_home"],
teamAway: json["team_away"],
teamHome: json["team_home"],
);
@override
String toString() {
return 'PartidoModel {awayGoals: $awayGoals, escudoAway: $escudoAway, escudoHome: $escudoHome, id: $id, name: $name, scoreAway: $scoreAway, scoreHome: $scoreHome, teamAway: $teamAway, teamHome: $teamHome}';
}
}
/// api
class Api {
final _dio = Dio(
BaseOptions(
baseUrl: 'https://scracdcs.herokuapp.com/',
),
);
Future<Temporada> getData() async {
final request = await _dio.get('json');
return Temporada.fromJson(request.data['Temporada'][0]);
}
}
class HomePartidosController extends GetxController {
final _isLoading = false.obs;
get isLoading => _isLoading.value;
// arranca null
final partidoSelected = Rx<PartidoModel>();
Temporada model;
final Api api;
HomePartidosController(this.api);
@override
void onReady() {
_getData();
}
void _getData() async {
_isLoading.value = true;
model = await api.getData();
_isLoading.value = false;
}
List<PartidoModel> get partidos => model?.jornada;
}
class _HomePartidos extends GetView<HomePartidosController> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Partidos'),
),
body: Obx(
() {
if (controller.isLoading) {
return Center(
child: Text(
'cargando ...',
style: Get.textTheme.headline2,
),
);
}
if (controller.partidos == null) {
return Text('esperando API request.');
}
return Row(
children: [
/// crea menu para seleccionar partido
Flexible(
flex: 2,
child: _PartidoMenu(partidos: controller.partidos),
),
VerticalDivider(width: 1, thickness: 1),
Flexible(
flex: 4,
// child: _PartidoMenu(partidos: controller.partidos),
child: _PartidoView(),
),
],
);
},
),
);
}
}
class _PartidoMenu extends StatelessWidget {
final List<PartidoModel> partidos;
const _PartidoMenu({Key key, this.partidos}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: Scrollbar(
child: ListView.separated(
separatorBuilder: (context, index) =>
Divider(height: 1, thickness: 1),
itemBuilder: (context, index) =>
_PartidoMenuItem(data: partidos[index]),
itemCount: partidos.length,
),
),
);
}
}
class _PartidoMenuItem extends GetView<HomePartidosController> {
final PartidoModel data;
const _PartidoMenuItem({Key key, this.data}) : super(key: key);
@override
Widget build(BuildContext context) {
return ListTile(
onTap: () => controller.partidoSelected(data),
title: Text(data.name, overflow: TextOverflow.ellipsis),
subtitle: Text(
'${data.teamHome} vs ${data.teamAway}',
overflow: TextOverflow.ellipsis,
),
leading: SizedBox(
width: 32,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Image.network(
data.escudoHome,
width: 24,
fit: BoxFit.contain,
),
Image.network(
data.escudoAway,
width: 24,
fit: BoxFit.contain,
),
],
),
),
);
}
}
class _PartidoView extends GetView<HomePartidosController> {
@override
Widget build(BuildContext context) {
// usamos reactive.
return Scrollbar(
child: SingleChildScrollView(
child: Container(
// color: Colors.white,
padding: EdgeInsets.all(8),
child: Obx(
() {
final partido = controller.partidoSelected.value;
if (partido == null) {
return Center(
child: Text(
'Selecciona un partido en el menu',
style:
Get.textTheme.headline6.copyWith(color: Colors.black38),
),
);
}
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: _EquipoView(
escudo: partido.escudoHome,
name: partido.teamHome,
score: partido.scoreHome,
goals: partido.homeGoals,
),
),
Container(
height: 120,
width: 1,
color: Get.theme.dividerColor.withOpacity(.1),
),
Expanded(
child: _EquipoView(
escudo: partido.escudoAway,
name: partido.teamAway,
score: partido.scoreAway,
goals: partido.awayGoals,
),
),
],
);
},
),
),
),
);
}
}
class _EquipoView extends StatelessWidget {
final String name;
final String score;
final String escudo;
final List<String> goals;
const _EquipoView({Key key, this.name, this.score, this.escudo, this.goals})
: super(key: key);
@override
Widget build(BuildContext context) {
List golesChilds = <Widget>[];
if (goals.isNotEmpty) {
golesChilds = [
SizedBox(height: 12),
Text(
'GOLES',
textAlign: TextAlign.left,
style: Get.textTheme.bodyText1.copyWith(fontSize: 12),
),
SizedBox(height: 12),
Wrap(
spacing: 6,
runSpacing: 6,
children: [
...goals.map((e) => Chip(
padding: EdgeInsets.zero,
backgroundColor: Colors.blue.shade700,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
label: Text(
e,
style: Get.textTheme.caption.copyWith(color: Colors.white),
),
)),
],
),
];
} else {
golesChilds = [
SizedBox(height: 20),
Text(
'Sin goles',
textAlign: TextAlign.center,
style: Get.textTheme.headline6.copyWith(color: Colors.black26),
),
];
}
return Container(
padding: EdgeInsets.all(8),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.network(
escudo,
width: 32,
fit: BoxFit.contain,
),
SizedBox(width: 10),
Flexible(
child: Text(
name,
overflow: TextOverflow.fade,
textAlign: TextAlign.center,
maxLines: 2,
style: Get.textTheme.headline5,
),
),
],
),
SizedBox(height: 24),
Text(
score,
textAlign: TextAlign.center,
style: Get.textTheme.headline1,
),
...golesChilds,
],
),
);
}
}
{
"Temporada": [
{
"Jornada 38": [
{
"away_goals": [
"AnsuFati 24'",
"L.Messi 34'75'",
"L.Suárez 44'",
"NélsonSemedo 57'"
],
"escudo_away": "https://assets-es.imgfoot.com/media/cache/60x60/club/fc-barcelona-1.png",
"escudo_home": "https://assets-es.imgfoot.com/media/cache/60x60/club/deportivo-alaves.png",
"home_goals": [],
"id": "550235",
"name": "Alavés en Barcelona",
"score_away": "5",
"score_home": "0",
"team_away": "Barcelona",
"team_home": "Alavés"
},
{
"away_goals": [],
"escudo_away": "https://assets-es.imgfoot.com/media/cache/60x60/club/real-betis.png",
"escudo_home": "https://assets-es.imgfoot.com/media/cache/60x60/club/real-valladolid.png",
"home_goals": [
"SergiGuardiola 45+1'",
"ÓscarPlano 63'"
],
"id": "550240",
"name": "Real Valladolid en Real Betis",
"score_away": "0",
"score_home": "2",
"team_away": "Real Betis",
"team_home": "Real Valladolid"
},
{
"away_goals": [],
"escudo_away": "https://assets-es.imgfoot.com/media/cache/60x60/club/eibar.png",
"escudo_home": "https://assets-es.imgfoot.com/media/cache/60x60/club/villarreal-2015834514682758915.png",
"home_goals": [
"A.ZamboAnguissa 71'",
"GerardMoreno 86'89'",
"MoiGómez 90+4'"
],
"id": "550237",
"name": "Villarreal en Eibar",
"score_away": "0",
"score_home": "4",
"team_away": "Eibar",
"team_home": "Villarreal"
},
{
"away_goals": [],
"escudo_away": "https://assets-es.imgfoot.com/media/cache/60x60/club/celta-de-vigo-6513619208928969762.png",
"escudo_home": "https://assets-es.imgfoot.com/media/cache/60x60/club/espanyol.png",
"home_goals": [],
"id": "550236",
"name": "Espanyol en Celta Vigo",
"score_away": "0",
"score_home": "0",
"team_away": "Celta Vigo",
"team_home": "Espanyol"
},
{
"away_goals": [
"SergioRamos 9'",
"Asensio 52'"
],
"escudo_away": "https://assets-es.imgfoot.com/media/cache/60x60/club/real-madrid-cf.png",
"escudo_home": "https://assets-es.imgfoot.com/media/cache/60x60/club/leganes.png",
"home_goals": [
"BryanGil 45+1'",
"R.Assalé78'"
],
"id": "550241",
"name": "Leganes en Real Madrid",
"score_away": "2",
"score_home": "2",
"team_away": "Real Madrid",
"team_home": "Leganes"
},
{
"away_goals": [
"L.Agbenyenu 45+1'",
"A.Budimir 65'"
],
"escudo_away": "https://assets-es.imgfoot.com/media/cache/60x60/club/majorque.png",
"escudo_home": "https://assets-es.imgfoot.com/media/cache/60x60/club/osasuna.png",
"home_goals": [
"Adrián 21'",
"IñigoPérez 68'"
],
"id": "550239",
"name": "Osasuna en Mallorca",
"score_away": "2",
"score_home": "2",
"team_away": "Mallorca",
"team_home": "Osasuna"
},
{
"away_goals": [],
"escudo_away": "https://assets-es.imgfoot.com/media/cache/60x60/club/athletic-bilbao.png",
"escudo_home": "https://assets-es.imgfoot.com/media/cache/60x60/club/grenade.png",
"home_goals": [
"Soldado 29'",
"AntonioPuertas 55'",
"CarlosFernández 67'",
"Montoro 90+3'"
],
"id": "550234",
"name": "Granada en Athletic Bilbao",
"score_away": "0",
"score_home": "4",
"team_away": "Athletic Bilbao",
"team_home": "Granada"
},
{
"away_goals": [
"A.Januzaj 87'"
],
"escudo_away": "https://assets-es.imgfoot.com/media/cache/60x60/club/real-sociedad.png",
"escudo_home": "https://assets-es.imgfoot.com/media/cache/60x60/club/atletico-madrid.png",
"home_goals": [
"Koke 30'"
],
"id": "550242",
"name": "Atletico Madrid en Real Sociedad",
"score_away": "1",
"score_home": "1",
"team_away": "Real Sociedad",
"team_home": "Atletico Madrid"
},
{
"away_goals": [],
"escudo_away": "https://assets-es.imgfoot.com/media/cache/60x60/club/valence.png",
"escudo_home": "https://assets-es.imgfoot.com/media/cache/60x60/sevilla.png",
"home_goals": [
"Reguilón 55'"
],
"id": "550243",
"name": "Sevilla FC en Valencia",
"score_away": "0",
"score_home": "1",
"team_away": "Valencia",
"team_home": "Sevilla FC"
},
{
"away_goals": [],
"escudo_away": "https://assets-es.imgfoot.com/media/cache/60x60/club/getafe.png",
"escudo_home": "https://assets-es.imgfoot.com/media/cache/60x60/club/levante-2263322039917214311.png",
"home_goals": [
"Coke 90+9'"
],
"id": "550238",
"name": "Levante en Getafe",
"score_away": "0",
"score_home": "1",
"team_away": "Getafe",
"team_home": "Levante"
}
]
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment