todas las clases funcionales
This commit is contained in:
@ -1,8 +1,11 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.flutter_project">
|
||||
|
||||
<application
|
||||
android:label="flutter_project"
|
||||
android:name="${applicationName}"
|
||||
android:icon="@mipmap/ic_launcher">
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true"
|
||||
@ -11,34 +14,32 @@
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- Specifies an Android theme to apply to this Activity as soon as
|
||||
the Android process has started. This theme is visible to the user
|
||||
while the Flutter UI initializes. After that, this theme continues
|
||||
to determine the Window background behind the Flutter UI. -->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"
|
||||
/>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
<!-- Especifica un tema de Android para aplicar a esta actividad tan pronto como se haya iniciado el proceso de Android. Este tema es visible para el usuario mientras la interfaz de usuario de Flutter se inicializa. Después de eso, este tema continúa determinando el fondo de la ventana detrás de la interfaz de usuario de Flutter. -->
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme" />
|
||||
</activity>
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
|
||||
<!-- No elimines los metadatos a continuación. Esto es utilizado por la herramienta Flutter para generar GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
</application>
|
||||
<!-- Required to query activities that can process text, see:
|
||||
https://developer.android.com/training/package-visibility?hl=en and
|
||||
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
|
||||
|
||||
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
|
||||
</application>
|
||||
|
||||
<!-- Requerido para consultar actividades que pueden procesar texto, ver: https://developer.android.com/training/package-visibility?hl=en y https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT. En particular, esto es utilizado por el motor Flutter en io.flutter.plugin.text.ProcessTextPlugin. -->
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.PROCESS_TEXT"/>
|
||||
<data android:mimeType="text/plain"/>
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
<!-- Permiso de Internet -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
</manifest>
|
||||
|
||||
@ -41,11 +41,13 @@ Future<void> launchAemetURL() async {
|
||||
final url = Uri.parse(urlString);
|
||||
|
||||
try {
|
||||
if (await canLaunch(urlString)) {
|
||||
await launch(urlString);
|
||||
|
||||
/* if (await canLaunch(urlString)) {
|
||||
await launch(urlString);
|
||||
} else {
|
||||
throw 'Could not launch $urlString';
|
||||
}
|
||||
}*/
|
||||
} catch (e) {
|
||||
throw Exception('Error al lanzar la URL de Aemet: $e');
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ List<Map<String, dynamic>> embalsesData = [];
|
||||
// Fondo con la imagen
|
||||
Positioned.fill(
|
||||
child: Image(
|
||||
image: AssetImage('assets/logo-fondo.png'),
|
||||
image: AssetImage('assets/logo-fondo-verde.png'),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
@ -123,6 +123,7 @@ List<Map<String, dynamic>> embalsesData = [];
|
||||
child: Text(
|
||||
nombreEmbalse!,
|
||||
style: TextStyle(
|
||||
fontSize : 25.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
@ -142,7 +143,7 @@ List<Map<String, dynamic>> embalsesData = [];
|
||||
(index) => Text(
|
||||
'${descripciones[index]}: ${listaElementos[index]}',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.normal,
|
||||
fontWeight: FontWeight.normal, fontSize : 20.0
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -35,7 +35,7 @@ class MyHomePage extends StatelessWidget {
|
||||
MaterialPageRoute(builder: (context) => const NoticiasPage()),
|
||||
);},
|
||||
child: SizedBox(
|
||||
width: 250.0,
|
||||
width: 300.0,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 20.0),
|
||||
child: Container(
|
||||
@ -49,7 +49,7 @@ class MyHomePage extends StatelessWidget {
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Color.fromARGB(255, 255, 255, 255),
|
||||
fontSize: 27.0,
|
||||
fontSize: 32.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
@ -65,7 +65,7 @@ class MyHomePage extends StatelessWidget {
|
||||
);
|
||||
},
|
||||
child: SizedBox(
|
||||
width: 250.0,
|
||||
width: 300.0,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 20.0),
|
||||
child: Container(
|
||||
@ -79,7 +79,7 @@ class MyHomePage extends StatelessWidget {
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 27.0,
|
||||
fontSize: 32.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
@ -95,7 +95,7 @@ class MyHomePage extends StatelessWidget {
|
||||
);
|
||||
},
|
||||
child: SizedBox(
|
||||
width: 250.0,
|
||||
width: 300.0,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 20.0),
|
||||
child: Container(
|
||||
@ -109,7 +109,7 @@ class MyHomePage extends StatelessWidget {
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 27.0,
|
||||
fontSize: 32.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
@ -122,7 +122,7 @@ class MyHomePage extends StatelessWidget {
|
||||
launchAemetURL();
|
||||
},
|
||||
child: SizedBox(
|
||||
width: 250.0,
|
||||
width: 300.0,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(bottom: 20.0),
|
||||
child: Container(
|
||||
@ -136,7 +136,7 @@ class MyHomePage extends StatelessWidget {
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 27.0,
|
||||
fontSize: 32.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
|
||||
@ -12,7 +12,7 @@ class NoticiasPage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _NoticiasPageState extends State<NoticiasPage> {
|
||||
Map<String, List<String>> noticiasPorTitulo = {};
|
||||
Map<String, List<Future<String>>> noticiasPorTitulo = {};
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -24,47 +24,71 @@ class _NoticiasPageState extends State<NoticiasPage> {
|
||||
final response = await http.get(Uri.parse('http://www.crcivan.com/escaparate/noticias.cgi?idpadre=92776&idempresa=31637'));
|
||||
if (response.statusCode == 200) {
|
||||
var document = htmlParser.parse(response.body);
|
||||
var dataElements = document.querySelectorAll('html > body > div > center > table > tbody > tr > td > div > center > table > tbody > tr > td > table > tbody > tr > td > font');
|
||||
var tituloElements = document.querySelectorAll('html > body > div > center > table > tbody > tr > td > div > center > table > tbody > tr > td > table > tbody > tr > td > b > a');
|
||||
|
||||
for (int i = 0; i < tituloElements.length; i++) {
|
||||
String titulo = tituloElements[i].text.trim();
|
||||
String noticia = dataElements[i].text.trim();
|
||||
|
||||
// Extrayendo el enlace href del elemento <a>
|
||||
var linkElement = tituloElements[i];
|
||||
String? link = linkElement.attributes['href'];
|
||||
|
||||
if (!noticiasPorTitulo.containsKey(titulo)) {
|
||||
noticiasPorTitulo[titulo] = [];
|
||||
if (link != null) {
|
||||
noticiasPorTitulo[titulo] = [cargarContenidoUrl(link)];
|
||||
}
|
||||
noticiasPorTitulo[titulo]?.add(noticia);
|
||||
}
|
||||
|
||||
// Esperar todas las promesas para que se resuelvan
|
||||
await Future.wait(noticiasPorTitulo.values.expand((element) => element).toList());
|
||||
|
||||
setState(() {});
|
||||
} else {
|
||||
throw Exception('fallo al cargar noticias');
|
||||
throw Exception('Fallo al cargar noticias');
|
||||
}
|
||||
}
|
||||
//Función para desplegar noticias desde los contenedores
|
||||
|
||||
/*Future<void> obtenerDatosNoticias() async {
|
||||
var linkElements = document.querySelectorAll('html > body > div > center > table > tbody > tr > td > div > center > table > tbody > tr > td > table > tbody > tr > td > a');
|
||||
String? link = linkElements[i].attributes['href'];
|
||||
if (response.statusCode == 200) {
|
||||
|
||||
for (int i = 0; i < tituloElements.length; i++) {
|
||||
String titulo = tituloElements[i].text.trim();
|
||||
String noticia = dataElements[i].text.trim();
|
||||
Future<String> 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 = '';
|
||||
|
||||
if (!noticiasPorTitulo.containsKey(titulo)) {
|
||||
noticiasPorTitulo[titulo] = [];
|
||||
for (var element in paragraphAndLists) {
|
||||
if (element.localName == 'p') {
|
||||
// Guardar el contenido del párrafo actual
|
||||
if (currentParagraphContent.isNotEmpty) {
|
||||
content += currentParagraphContent + '\n';
|
||||
currentParagraphContent = '';
|
||||
}
|
||||
currentParagraphContent += element.text.trim() + '\n';
|
||||
} else if (element.localName == 'ul') {
|
||||
// Si hay un párrafo antes de la lista, agregarlo al contenido
|
||||
if (currentParagraphContent.isNotEmpty) {
|
||||
content += currentParagraphContent + '\n';
|
||||
currentParagraphContent = '';
|
||||
}
|
||||
// Agregar la lista al contenido
|
||||
var listItems = element.querySelectorAll('li');
|
||||
for (var listItem in listItems) {
|
||||
content += '- ${listItem.text.trim()}\n';
|
||||
}
|
||||
noticiasPorTitulo[titulo]?.add(noticia);
|
||||
}
|
||||
|
||||
setState(() {});
|
||||
} else {
|
||||
throw Exception('fallo al cargar noticias');
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
// Agregar el último párrafo si no hay lista después
|
||||
if (currentParagraphContent.isNotEmpty) {
|
||||
content += currentParagraphContent + '\n';
|
||||
}
|
||||
|
||||
return content;
|
||||
} else {
|
||||
throw Exception('Fallo al cargar contenido de URL: $url');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -74,7 +98,7 @@ class _NoticiasPageState extends State<NoticiasPage> {
|
||||
children: [
|
||||
Positioned.fill(
|
||||
child: Image(
|
||||
image: AssetImage('assets/logo-fondo.png'),
|
||||
image: AssetImage('assets/logo-fondo-verde.png'),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
@ -82,24 +106,40 @@ class _NoticiasPageState extends State<NoticiasPage> {
|
||||
itemCount: noticiasPorTitulo.length,
|
||||
itemBuilder: (context, index) {
|
||||
String titulo = noticiasPorTitulo.keys.elementAt(index);
|
||||
List<String>? noticias = noticiasPorTitulo[titulo];
|
||||
List<Future<String>>? noticias = noticiasPorTitulo[titulo];
|
||||
|
||||
return ExpansionTile(
|
||||
title: Text(
|
||||
titulo,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
children: noticias != null
|
||||
? noticias.map((noticia) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
noticia,
|
||||
style: TextStyle(fontSize: 16.0),
|
||||
),
|
||||
);
|
||||
}).toList()
|
||||
: [],
|
||||
return FutureBuilder<List<String>>(
|
||||
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(),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
@ -64,7 +64,7 @@ Widget build(BuildContext context) {
|
||||
// Fondo con la imagen
|
||||
Positioned.fill(
|
||||
child: Image(
|
||||
image: AssetImage('assets/logo-fondo.png'),
|
||||
image: AssetImage('assets/logo-fondo-verde.png'),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
@ -80,7 +80,7 @@ Widget build(BuildContext context) {
|
||||
if (hasMes)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10.0), // Add padding to the divider
|
||||
child: Divider(color: Colors.blue, thickness: 3.0), // Divider antes del párrafo
|
||||
child: Divider(color: Colors.green, thickness: 3.0), // Divider antes del párrafo
|
||||
),
|
||||
hasText
|
||||
? ListTile(
|
||||
@ -89,7 +89,7 @@ Widget build(BuildContext context) {
|
||||
datos[index],
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: hasMes ? Color.fromARGB(255, 0, 0, 0) : Color.fromARGB(255, 0, 0, 0), fontWeight : FontWeight.bold
|
||||
color: hasMes ? Color.fromARGB(255, 0, 0, 0) : Color.fromARGB(255, 0, 0, 0), fontWeight : FontWeight.bold, fontSize : 22.0
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -98,7 +98,7 @@ Widget build(BuildContext context) {
|
||||
if (hasMes)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 100.0), // Add padding to the divider
|
||||
child: Divider(color: Colors.blue, thickness: 1.0), // Divider después del párrafo
|
||||
child: Divider(color: Colors.green, thickness: 1.0), // Divider después del párrafo
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user