From 20a4cb7ab25d46a5316d015b74f35a4879309e63 Mon Sep 17 00:00:00 2001 From: nadia Date: Tue, 21 May 2024 16:52:01 +0200 Subject: [PATCH] aplicacion terminada, clase widget creada y separacion bloc --- lib/BloC/DataService.dart | 31 +++++ lib/BloC/contenedores_event.dart | 2 +- lib/pages/embalses | 184 ++++++++++------------------- lib/pages/my_home_page.dart | 29 ++--- lib/pages/noticias | 153 ++++++++++++------------ lib/pages/pregon | 102 ++++++++-------- lib/widgets/background_widget.dart | 22 ++++ 7 files changed, 248 insertions(+), 275 deletions(-) create mode 100644 lib/BloC/DataService.dart create mode 100644 lib/widgets/background_widget.dart diff --git a/lib/BloC/DataService.dart b/lib/BloC/DataService.dart new file mode 100644 index 0000000..11710b8 --- /dev/null +++ b/lib/BloC/DataService.dart @@ -0,0 +1,31 @@ +import 'package:http/http.dart' as http; +import 'package:html/parser.dart' as htmlParser; + +class DataService { + Future>> obtenerDatos() async { + final response = await http.get(Uri.parse('http://www.crcivan.com/escaparate/noticias.cgi?idnoticias=192683')); + if (response.statusCode == 200) { + final document = htmlParser.parse(response.body); + + final filaTabla = document.querySelectorAll('html > body > div > center > table > tbody > tr > td > div > center > table > tbody > tr > td > table > tbody > tr > td > font > font > table > tbody > tr'); + + List> embalsesData = []; + + for (var fila in filaTabla) { + var nombreElemento = fila.querySelector('td > p > span'); + var elementos = fila.querySelectorAll('td > span'); + + if (nombreElemento != null && elementos.isNotEmpty) { + var nombre = nombreElemento.text; + var listaElementos = elementos.map((elemento) => elemento.text).toList(); + + var embalseMap = {'nombre': nombre, 'elementos': listaElementos}; + embalsesData.add(embalseMap); + } + } + return embalsesData; + } else { + throw Exception('Error al obtener datos'); + } + } +} diff --git a/lib/BloC/contenedores_event.dart b/lib/BloC/contenedores_event.dart index 0ee508e..2f03f08 100644 --- a/lib/BloC/contenedores_event.dart +++ b/lib/BloC/contenedores_event.dart @@ -16,7 +16,7 @@ class MyBloc extends Cubit { } //mejorar código -Future> obtenerDatos(String url) async { +Future> obtenerDatos() async { final response = await http.get(Uri.parse('http://www.crcivan.com/escaparate/noticias.cgi?idnoticias=192683')); if (response.statusCode == 200) { final document = htmlParser.parse(response.body); diff --git a/lib/pages/embalses b/lib/pages/embalses index e5e5e5b..a31f829 100644 --- a/lib/pages/embalses +++ b/lib/pages/embalses @@ -1,7 +1,10 @@ import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; +import 'package:flutter_project/BloC/DataService.dart'; import 'package:html/parser.dart' as htmlParser; +import 'package:flutter_project/BloC/contenedores_event.dart'; import 'package:flutter_project/bars/app_bar'; +import 'package:flutter_project/widgets/background_widget.dart'; import 'package:flutter_project/bars/bottom_bar'; class EmbalsesPage extends StatefulWidget { @@ -12,7 +15,8 @@ class EmbalsesPage extends StatefulWidget { } class _EmbalsesPageState extends State { -List> embalsesData = []; + final DataService dataService = DataService(); + List> embalsesData = []; List descripciones = ['Cota (m)', 'Volumen (Hm3)', 'Entrada (l/s)', 'Salida (l/s)']; @override @@ -22,144 +26,84 @@ List> embalsesData = []; } Future obtenerDatos() async { - final response = await http.get(Uri.parse('http://www.crcivan.com/escaparate/noticias.cgi?idnoticias=192683')); - if (response.statusCode == 200) { - final document = htmlParser.parse(response.body); - - // Buscar los elementos dentro de la estructura específica - final elementosSpan = document.querySelectorAll('html > body > div > center > table > tbody > tr > td > div > center > table > tbody > tr > td > table > tbody > tr > td > font > font > table > tbody > tr > td > span'); - final nombreEmbalses = document.querySelectorAll('html > body > div > center > table > tbody > tr > td > div > center > table > tbody > tr > td > table > tbody > tr > td > font > font > table > tbody > tr > td > p > span'); - - final filaTabla = document.querySelectorAll('html > body > div > center > table > tbody > tr > td > div > center > table > tbody > tr > td > table > tbody > tr > td > font > font > table > tbody > tr'); - // Limpiar la lista de datos antes de actualizarla + try { + final data = await dataService.obtenerDatos(); setState(() { - embalsesData.clear(); - }); - - /* for (var i = 0; i < filaTabla.length; i++){ - var nombre[i] = filaTabla.child('td > p > span'); - List elemento[i] = filaTabla.child('td > span'); - embalseData.add(nombre, elemento); - }*/ - - // Agregar textos de los elementos a la lista - /* for (var i = 0; i < elementosSpan.length; i++) { - final elemento = elementosSpan[i]; - final style = elemento.attributes['style']; - if (style != null && style.contains('font-size: 12pt;')) { - setState(() { - // Verificar si el índice es válido antes de agregar los datos a embalsesData - if (i < nombreEmbalses.length) { - embalsesData.add({ - 'nombre': nombreEmbalses[i].text, - 'otroTexto': elemento.text, - }); - } - }); - } - } */ - - for (var fila in filaTabla) { - var nombreElemento = fila.querySelector('td > p > span'); - var elementos = fila.querySelectorAll('td > span'); - - if (nombreElemento != null && elementos.isNotEmpty) { - var nombre = nombreElemento.text; - var listaElementos = elementos.map((elemento) => elemento.text).toList(); - - // Crear un mapa con el nombre del embalse y sus elementos - var embalseMap = {'nombre': nombre, 'elementos': listaElementos}; - - // Agregar el mapa a la lista de embalsesData - setState(() { - embalsesData.add(embalseMap); - }); - } -} - - - } else { - throw Exception('Error al cargar los datos de embalses'); + embalsesData = data; + }); + } catch (e) { + print('Error: $e'); } - } @override Widget build(BuildContext context) { return Scaffold( appBar: const CustomAppBar(), - body: Stack( - children: [ - // Fondo con la imagen - Positioned.fill( - child: Image( - image: AssetImage('assets/logo-fondo-verde.png'), - fit: BoxFit.cover, - ), - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: ListView.builder( - itemCount: embalsesData.length, - itemBuilder: (context, index) { - final embalseData = embalsesData[index]; - final nombreEmbalse = embalseData['nombre']; - final listaElementos = embalseData['elementos']; + body: BackgroundWidget( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: ListView.builder( + itemCount: embalsesData.length, + itemBuilder: (context, index) { + final embalseData = embalsesData[index]; + final nombreEmbalse = embalseData['nombre']; + final listaElementos = embalseData['elementos']; - return Padding( - padding: const EdgeInsets.only(bottom: 8.0), - child: Container( - decoration: BoxDecoration( - color: Colors.white.withOpacity(0.5), - borderRadius: BorderRadius.circular(10.0), - ), - child: Column( - children: [ - Row( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - nombreEmbalse!, - style: TextStyle( - fontSize : 25.0, - fontWeight: FontWeight.bold, - ), + return Padding( + padding: const EdgeInsets.only(bottom: 8.0), + child: Container( + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.5), + borderRadius: BorderRadius.circular(10.0), + ), + child: Column( + children: [ + Row( + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + nombreEmbalse!, + style: const TextStyle( + fontSize: 25.0, + fontWeight: FontWeight.bold, ), ), ), - ], - ), - Row( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: List.generate( - listaElementos.length, - (index) => Text( - '${descripciones[index]}: ${listaElementos[index]}', - style: TextStyle( - fontWeight: FontWeight.normal, fontSize : 20.0 - ), + ), + ], + ), + Row( + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: List.generate( + listaElementos.length, + (index) => Text( + '${descripciones[index]}: ${listaElementos[index]}', + style: const TextStyle( + fontWeight: FontWeight.normal, + fontSize: 20.0, ), ), ), ), ), - ], - ), - ], - ), + ), + ], + ), + ], ), - ); - }, - ), + ), + ); + }, ), - ], + ), ), bottomNavigationBar: const CustomBottomBar(), ); diff --git a/lib/pages/my_home_page.dart b/lib/pages/my_home_page.dart index 355dd78..b0d6f25 100644 --- a/lib/pages/my_home_page.dart +++ b/lib/pages/my_home_page.dart @@ -5,8 +5,7 @@ import 'package:flutter_project/BloC/contenedores_event.dart'; import 'package:flutter_project/pages/noticias'; import 'package:flutter_project/pages/pregon'; import 'package:flutter_project/pages/embalses'; - - +import 'package:flutter_project/widgets/background_widget.dart'; class MyHomePage extends StatelessWidget { const MyHomePage({Key? key, required this.title}) : super(key: key); @@ -16,24 +15,16 @@ class MyHomePage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: const CustomAppBar(), - body: Container( - - decoration: const BoxDecoration( - image: DecorationImage( - image: AssetImage('assets/logo-fondo-verde.png'), - fit: BoxFit.cover, - ), - - ), + body: BackgroundWidget( child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ InkWell( onTap: () { Navigator.push( - context, - MaterialPageRoute(builder: (context) => const NoticiasPage()), - );}, + context, + MaterialPageRoute(builder: (context) => const NoticiasPage()), + );}, child: SizedBox( width: 300.0, child: Padding( @@ -41,14 +32,14 @@ class MyHomePage extends StatelessWidget { child: Container( padding: const EdgeInsets.all(8.0), decoration: BoxDecoration( - color: Color.fromARGB(255, 78, 169, 6), + color: const Color.fromARGB(255, 78, 169, 6), borderRadius: BorderRadius.circular(7.0), ), child: const Text( 'Noticias', textAlign: TextAlign.center, style: TextStyle( - color: Color.fromARGB(255, 255, 255, 255), + color: Colors.white, fontSize: 32.0, fontWeight: FontWeight.bold, ), @@ -71,7 +62,7 @@ class MyHomePage extends StatelessWidget { child: Container( padding: const EdgeInsets.all(8.0), decoration: BoxDecoration( - color: Color.fromARGB(255, 78, 169, 6), + color: const Color.fromARGB(255, 78, 169, 6), borderRadius: BorderRadius.circular(7.0), ), child: const Text( @@ -101,7 +92,7 @@ class MyHomePage extends StatelessWidget { child: Container( padding: const EdgeInsets.all(8.0), decoration: BoxDecoration( - color: Color.fromARGB(255, 78, 169, 6), + color: const Color.fromARGB(255, 78, 169, 6), borderRadius: BorderRadius.circular(7.0), ), child: const Text( @@ -128,7 +119,7 @@ class MyHomePage extends StatelessWidget { child: Container( padding: const EdgeInsets.all(8.0), decoration: BoxDecoration( - color: Color.fromARGB(255, 78, 169, 6), + color: const Color.fromARGB(255, 78, 169, 6), borderRadius: BorderRadius.circular(7.0), ), child: const Text( diff --git a/lib/pages/noticias b/lib/pages/noticias index b26db67..427745f 100644 --- a/lib/pages/noticias +++ b/lib/pages/noticias @@ -3,6 +3,8 @@ import 'package:http/http.dart' as http; import 'package:flutter_project/bars/app_bar'; import 'package:flutter_project/bars/bottom_bar'; import 'package:html/parser.dart' as htmlParser; +import 'package:flutter_project/widgets/background_widget.dart'; + class NoticiasPage extends StatefulWidget { const NoticiasPage({Key? key}) : super(key: key); @@ -47,100 +49,91 @@ class _NoticiasPageState extends State { } Future cargarContenidoUrl(String url) async { - final response = await http.get(Uri.parse(url)); - if (response.statusCode == 200) { - var document = htmlParser.parse(response.body); - var paragraphAndLists = document.querySelectorAll('html > body > div > center > table > tbody > tr > td > div > center > table > tbody > tr > td > table > tbody > tr > td > font > font > p, html > body > div > center > table > tbody > tr > td > div > center > table > tbody > tr > td > table > tbody > tr > td > font > font > ul'); - - String content = ''; - String currentParagraphContent = ''; + final response = await http.get(Uri.parse(url)); + if (response.statusCode == 200) { + var document = htmlParser.parse(response.body); + var paragraphAndLists = document.querySelectorAll('html > body > div > center > table > tbody > tr > td > div > center > table > tbody > tr > td > table > tbody > tr > td > font > font > p, html > body > div > center > table > tbody > tr > td > div > center > table > tbody > tr > td > table > tbody > tr > td > font > font > ul'); + + String content = ''; + String currentParagraphContent = ''; - for (var element in paragraphAndLists) { - if (element.localName == 'p') { - if (currentParagraphContent.isNotEmpty) { - content += currentParagraphContent + '\n'; - currentParagraphContent = ''; - } - currentParagraphContent += element.text.trim() + '\n'; - } else if (element.localName == 'ul') { - if (currentParagraphContent.isNotEmpty) { - content += currentParagraphContent + '\n'; - currentParagraphContent = ''; - } - var listItems = element.querySelectorAll('li'); - for (var listItem in listItems) { - content += '- ${listItem.text.trim()}\n'; + for (var element in paragraphAndLists) { + if (element.localName == 'p') { + if (currentParagraphContent.isNotEmpty) { + content += currentParagraphContent + '\n'; + currentParagraphContent = ''; + } + currentParagraphContent += element.text.trim() + '\n'; + } else if (element.localName == 'ul') { + if (currentParagraphContent.isNotEmpty) { + content += currentParagraphContent + '\n'; + currentParagraphContent = ''; + } + var listItems = element.querySelectorAll('li'); + for (var listItem in listItems) { + content += '- ${listItem.text.trim()}\n'; + } } } - } - if (currentParagraphContent.isNotEmpty) { - content += currentParagraphContent + '\n'; - } + if (currentParagraphContent.isNotEmpty) { + content += currentParagraphContent + '\n'; + } - return content; - } else { - throw Exception('Fallo al cargar contenido de URL: $url'); + return content; + } else { + throw Exception('Fallo al cargar contenido de URL: $url'); + } } -} - @override Widget build(BuildContext context) { return Scaffold( appBar: const CustomAppBar(), - body: Stack( - children: [ - Positioned.fill( - child: Image( - image: AssetImage('assets/logo-fondo-verde.png'), - fit: BoxFit.cover, - ), - ), - ListView.builder( - itemCount: noticiasPorTitulo.length, - itemBuilder: (context, index) { - String titulo = noticiasPorTitulo.keys.elementAt(index); - List>? noticias = noticiasPorTitulo[titulo]; + body: BackgroundWidget( + child: ListView.builder( + itemCount: noticiasPorTitulo.length, + itemBuilder: (context, index) { + String titulo = noticiasPorTitulo.keys.elementAt(index); + List>? noticias = noticiasPorTitulo[titulo]; - return FutureBuilder>( - future: Future.wait(noticias ?? []), - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return CircularProgressIndicator(); - } else if (snapshot.hasError) { - return Text('Error: ${snapshot.error}'); - } else if (!snapshot.hasData) { - return Text('No hay datos'); - } else { - return Container( - color: Colors.white.withOpacity(0.5), // Fondo blanco con 50% de opacidad - margin: const EdgeInsets.all(8.0), - padding: const EdgeInsets.all(8.0), - child: ExpansionTile( - title: Text( - titulo, - style: TextStyle(fontWeight: FontWeight.bold), - ), - children: snapshot.data!.map((noticia) { - return Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - noticia, - style: TextStyle(fontSize: 16.0), - ), - ); - }).toList(), + return FutureBuilder>( + future: Future.wait(noticias ?? []), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return CircularProgressIndicator(); + } else if (snapshot.hasError) { + return Text('Error: ${snapshot.error}'); + } else if (!snapshot.hasData) { + return Text('No hay datos'); + } else { + return Container( + color: Colors.white.withOpacity(0.5), // Fondo blanco con 50% de opacidad + margin: const EdgeInsets.all(8.0), + padding: const EdgeInsets.all(8.0), + child: ExpansionTile( + title: Text( + titulo, + style: TextStyle(fontWeight: FontWeight.bold), ), - ); - } - }, - ); - }, - ), - ], + children: snapshot.data!.map((noticia) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + noticia, + style: TextStyle(fontSize: 16.0), + ), + ); + }).toList(), + ), + ); + } + }, + ); + }, + ), ), bottomNavigationBar: const CustomBottomBar(), ); } -} +} \ No newline at end of file diff --git a/lib/pages/pregon b/lib/pages/pregon index 7ad8c5a..dc4f537 100644 --- a/lib/pages/pregon +++ b/lib/pages/pregon @@ -4,6 +4,9 @@ import 'package:html/parser.dart' as htmlParser; import 'package:html/dom.dart' as htmlDom; import 'package:flutter_project/bars/app_bar'; import 'package:flutter_project/bars/bottom_bar'; +import 'package:flutter_project/widgets/background_widget.dart'; + + class Pregon extends StatefulWidget { const Pregon({Key? key}) : super(key: key); @@ -35,41 +38,32 @@ class _PregonState extends State { }); // Agregar textos de los elementos

a la lista, evitando los que contienen solo espacios - for (var elemento in elementosParrafos) { - final texto = elemento.text.trim(); // Eliminar espacios al inicio y al final del texto - if (texto.isNotEmpty) { - setState(() { - datos.add(texto); - }); + for (var elemento in elementosParrafos) { + final texto = elemento.text.trim(); // Eliminar espacios al inicio y al final del texto + if (texto.isNotEmpty) { + setState(() { + datos.add(texto); + }); + } } - } } else { throw Exception('Error al cargar los datos'); } } -@override -Widget build(BuildContext context) { - // Lista de nombres de los meses del año - final meses = [ - 'enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', - 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre' - ]; + @override + Widget build(BuildContext context) { + // Lista de nombres de los meses del año + final meses = [ + 'enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', + 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre' + ]; - return Scaffold( - appBar: const CustomAppBar(), - body: Stack( - children: [ - // Fondo con la imagen - Positioned.fill( - child: Image( - image: AssetImage('assets/logo-fondo-verde.png'), - fit: BoxFit.cover, - ), - ), - // Contenedor para los párrafos - Center( + return Scaffold( + appBar: const CustomAppBar(), + body: BackgroundWidget( + child: Center( child: ListView.builder( itemCount: datos.length, itemBuilder: (context, index) { @@ -78,38 +72,36 @@ Widget build(BuildContext context) { return Column( children: [ if (hasMes) - Padding( - padding: const EdgeInsets.symmetric(horizontal: 10.0), - child: Divider(color: Colors.green, thickness: 3.0), // Divider antes del párrafo - ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10.0), + child: Divider(color: Colors.green, thickness: 3.0), // Divider antes del párrafo + ), hasText - ? ListTile( - title: Center( - child: Text( - datos[index], - textAlign: TextAlign.center, - style: TextStyle( - color: hasMes ? Color.fromARGB(255, 0, 0, 0) : Color.fromARGB(255, 0, 0, 0), fontWeight : FontWeight.bold, fontSize : 22.0 - ), + ? ListTile( + title: Center( + child: Text( + datos[index], + textAlign: TextAlign.center, + style: TextStyle( + color: hasMes ? Color.fromARGB(255, 0, 0, 0) : Color.fromARGB(255, 0, 0, 0), fontWeight : FontWeight.bold, fontSize : 22.0 ), ), - ) - : SizedBox.shrink(), - if (hasMes) - Padding( - padding: const EdgeInsets.symmetric(horizontal: 100.0), - child: Divider(color: Colors.green, thickness: 1.0), // Divider después del párrafo - ), - ], - ); - }, + ), + ) + : SizedBox.shrink(), + if (hasMes) + Padding( + padding: const EdgeInsets.symmetric(horizontal: 100.0), + child: Divider(color: Colors.green, thickness: 1.0), // Divider después del párrafo + ), + ], + ); + }, shrinkWrap: true, // Ajusta el tamaño de ListView al contenido ), ), - ], - ), - bottomNavigationBar: const CustomBottomBar(), - ); -} - + ), + bottomNavigationBar: const CustomBottomBar(), + ); + } } \ No newline at end of file diff --git a/lib/widgets/background_widget.dart b/lib/widgets/background_widget.dart new file mode 100644 index 0000000..1236699 --- /dev/null +++ b/lib/widgets/background_widget.dart @@ -0,0 +1,22 @@ +import 'package:flutter/material.dart'; + +class BackgroundWidget extends StatelessWidget { + final Widget child; + + const BackgroundWidget({required this.child, Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + Positioned.fill( + child: Image.asset( + 'assets/logo-fondo-verde.png', + fit: BoxFit.cover, + ), + ), + child, + ], + ); + } +}