Saltar al contenido

tire hacia abajo para ACTUALIZAR en Flutter

Ramón, miembro de nuestro staff, nos ha hecho el favor de crear esta sección ya que conoce perfectamente el tema.

Solución:

Ejemplo básico

A continuación se muestra una clase de estado de StatefulWidget, donde:

  • a ListView está envuelto en un RefreshIndicator
    • words variable de estado es su fuente de datos
  • onRefresh llamadas _pullRefresh función para actualizar ListView
    • _pullRefresh es una función asíncrona, que no devuelve nada (una Future)
    • Cuándo _pullRefreshSe completa la solicitud de datos de ejecución prolongada, words la variable miembro/estado se actualiza en un setState() llamar a reconstruir ListView para mostrar nuevos datos
import 'package:english_words/english_words.dart';

class _PullToRefreshPageState extends State 
  List words = generateWordPairs().take(5).toList();

  @override
  Widget build(BuildContext context) 
    return RefreshIndicator(
      onRefresh: _pullRefresh,
      child: ListView.builder(
        itemCount: words.length,
        itemBuilder: (context, index) 
          return ListTile(
            title: Text(words[index].asPascalCase),
          );
        ,),
    );
  

  Future _pullRefresh() async 
    List freshWords = await WordDataSource().getFutureWords(delay: 2);
    setState(() 
      words = freshWords;
    );
    // why use freshWords var? https://stackoverflow.com/a/52992836/2301224
  


class WordDataSource 
  Future> getFutureWords(int size = 5, int delay = 5) async 
    await Future.delayed(Duration(seconds: delay));
    return generateWordPairs().take(5).toList();
  

notas

  • Si tu asíncrono onRefresh función se completa muy rápidamente, es posible que desee agregar un await Future.delayed(Duration(seconds: 2)); después, solo para que la UX sea más agradable.
  • Esto le da tiempo al usuario para completar un gesto de deslizar/desplegar hacia abajo y para que el indicador de actualización se muestre/anime/gire indicando que se han obtenido los datos.

Ejemplo de FutureBuilder

Aquí hay otro ejemplo, usando un FutureBuilder, que es común cuando se obtienen datos de una base de datos o una fuente HTTP.

class _PullToRefreshFuturePageState extends State 
  Future> futureWords;

  @override
  void initState() 
    super.initState();
    futureWords = WordDataSource().getFutureWords(delay: 2);
  

  @override
  Widget build(BuildContext context) 
    return FutureBuilder>(
      //initialData: [],
      future: futureWords,
      builder: (context, snapshot) 
        return RefreshIndicator(
          child: _listView(snapshot),
          onRefresh: _pullRefresh,
        );
      ,
    );
  

  Widget _listView(AsyncSnapshot snapshot) 
    if (snapshot.hasData) 
      return ListView.builder(
        itemCount: snapshot.data.length,
        itemBuilder: (context, index) 
          return ListTile(
            title: Text(snapshot.data[index].asPascalCase),
          );
        ,);
    
    else 
      return Center(
        child: Text('Loading data...'),
      );
    
  

  Future _pullRefresh() async 
    List freshFutureWords = await WordDataSource().getFutureWords(delay: 2);
    setState(() 
      futureWords = Future.value(freshFutureWords);
    );
  

notas

  • getFutureWords() La función es la misma que en el Ejemplo básico arriba, pero los datos están envueltos en un Future.value() ya que FutureBuilder espera un Future
  • según Rémi, Collin y otros semidioses de Dart/Flutter, es una buena práctica actualizar las variables de miembro de Stateful Widget en el interiorsetState() (futureWords en el ejemplo de FutureBuilder & words en el ejemplo básico), después sus funciones de obtención de datos asincrónicos de larga ejecución se han completado.
    • https://stackoverflow.com/a/52992836/2301224
  • si intentas hacer setState asyncobtendrás una excepción
  • actualizando variables miembro fuera de setState y tener un vacío setState cierre, puede dar lugar a advertencias de análisis de códigos/bofetadas en el futuro

No estoy seguro acerca de los futuros, pero para el indicador de actualización debe devolver un void así que usa algo como

RefreshIndicator(
                onRefresh: () async  
                  await getData().then((lA) 
                    if (lA is Future) 
                      setState(() 
                        reportList = lA;
                      );
                      return;
                     else 
                      setState(() 
                       //error
                      );
                      return;
                    
                  );

                  return;
                ,

¡Intenta eso y dejame saber!

EDITAR:

Bueno, entonces prueba esto dentro de tu método de actualización

          setState(() 
            reportList = getReport();  
          );
          return reportList;

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *