latest

ListView con scroll infinito. Obteniendo datos de un servidor remoto.

En esta nueva lección del curso de Flutter vamos a ver otro procedimiento diferente para construir un ListView. El Listview construido permitirá hacer scroll "infinito", añadiendo y renderizando nuevos items que se irán adquiriendo a medida que se alcanza el final de la lista al hacer scroll. Los items estarán compuestos por imágenes cuyas URLs se obtendrán realizando peticiones HTTP a un servidor remoto (fetching).

El aspecto de la interfaz de usuario incluyendo el Listview dinámico se muestra a continuación:

Abajo se expone el código de este ejemplo:

import 'package:flutter/material.dart';

import 'dart:io';
import 'dart:convert';

class ListaInfinita extends StatefulWidget {
  @override
  _ListaInfinitaState createState() => _ListaInfinitaState();
}

class _ListaInfinitaState extends State<ListaInfinita> {

  ScrollController _controladorScroll;
  
  // Propiedad dinámica
  List<String> imagenes = new List<String>();
  
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _controladorScroll = new ScrollController();
    fetchCuatro();

    _controladorScroll.addListener((){
      if(_controladorScroll.position.pixels == 
        _controladorScroll.position.maxScrollExtent){
          fetchCuatro();
      }
    });
  }

  @override
  void dispose() {
    // TODO: implement dispose
    _controladorScroll.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: imagenes.length,
      itemBuilder: (context, int index){
        return Container(
          child: Image.network(
            imagenes[index], 
            fit: BoxFit.fill
          )
        );
      },
      controller: _controladorScroll,
    );
  }

  void fetch() async {
    HttpClient http = HttpClient();
    try{
      var uri = Uri.parse("https://dog.ceo/api/breeds/image/random"); 
      var request = await http.getUrl(uri);
      var response = await request.close();
      if (response.statusCode == 200){
        var responseBody = await response.transform(utf8.decoder).join();
        setState((){
           imagenes.add( json.decode(responseBody)['message'] );
        }); 
      }
    } catch(exception){
      print(exception);
    }
  }
  
  void fetchCuatro() {
    for (int i = 0; i < 4; i++){
      fetch();
    }
  }
}

En este ocasión, el ListView se construye dentro en el método build() del State de un StatefulWidget. Esto tiene sentido dado que se trata de una lista dinámica que irá creciendo en tamaño según vamos haciendo scroll vertical hacia abajo. Para tal fin, se mantiene un List<String> (imagenes) que mantiene cadenas con direcciones URL de las imágenes que están contenidas en el ListView. Así pues, la List<String> imagenes es una propiedad dinámica del widget que, básicamente, actualizaremos cuando el scroll alcance la parte inferior de la página (if(_controladorScroll.position.pixels == _controladorScroll.position.maxScrollExtent)).

Author image
Iván González is postdoctoral researcher at the Castilla-La Mancha University.
Ciudad Real (Spain)