Использование RefreshIndicator для обновления списка из веб-службы

Я не понимаю использования RefreshIndicator во Flutter. У меня есть список пациентов из клиники. Список пациентов может измениться после его отображения в приложении, другие пользователи приложения могут добавлять новых пациентов или удалять существующих пациентов.

Мне нужно реализовать способ обновления списка пациентов при необходимости.

Вот фрагмент кода, в котором я показываю элементы списка:

//LISTA DE PACIENTES
            Expanded(
              child: Consumer(
                builder: (context, watch, child) {
                  var value = watch(clinicaIdStateProvider).state;

                  return Container(
                    child: FutureBuilder(
                      future: fetchPacientes(value),
                      builder: (context, snapshot) {

                        if (snapshot.hasData) {
                          var filteredList = snapshot.data;
                          print("a minusculas:"+_controller.text.toLowerCase());
                          filteredList = filteredList.where((element) => (
                              element.nombre_completo.toLowerCase().contains(_controller.text.toLowerCase()) ||
                                  element.NHC.toLowerCase().contains(_controller.text.toLowerCase()) ||
                                  element.apellidos.toLowerCase().contains(_controller.text.toLowerCase())
                          )).toList();

                          print("texto filtrado="+_controller.text.toLowerCase());


                          return ListView.builder(
                            itemCount: filteredList.length,
                            shrinkWrap: true,
                            itemBuilder: (BuildContext context, index) {
                              Paciente paciente = filteredList[index];
                              return new GestureDetector(
                                onTap: () {
                                  print("paciente seleccionada nbre: " +
                                      '${paciente.nombre_completo}');
                                },
                                child: new Card(

                                  elevation: 6,
                                  child: new Container(

                                    child: Column(
                                      children: [
                                        Padding(
                                          padding: const EdgeInsets.all(4.0),
                                          child: Row(
                                            mainAxisAlignment:
                                                MainAxisAlignment.spaceBetween,
                                            children: [
                                              Padding(
                                                padding:
                                                    const EdgeInsets.all(4.0),
                                                child: Text(
                                                  "${paciente.apellidos}" +
                                                      ", " +
                                                      "${paciente.nombre_completo}",
                                                  style:
                                                      TextStyle(fontSize: 18),
                                                ),
                                              ),
                                              Column(
                                                children: [
                                                  Container(
                                                    decoration: BoxDecoration(
                                                        color:
                                                            AppColors.azulCapenergy,
                                                        border: Border.all(
                                                          color: AppColors
                                                              .azulCapenergy,
                                                        ),
                                                        borderRadius:
                                                            BorderRadius.all(
                                                                Radius.circular(
                                                                    12))),
                                                    child: Padding(
                                                      padding:
                                                          const EdgeInsets.all(4.0),
                                                      child: Text(
                                                        "NHC: ${paciente.NHC}",
                                                        style: TextStyle(
                                                            color: AppColors
                                                                .blancoCapenergy,
                                                            fontSize: 16),
                                                      ),
                                                    ),

                                                  ),
                                                  SizedBox(height: 3,),
                                                  FlatButton(
                                                    onPressed: (){
                                                      print("boton agenda pulsado de ${paciente.nombre_completo}");
                                                    },
                                                    child: Container(
                                                      decoration: BoxDecoration(
                                                          color:
                                                          Colors.transparent,
                                                          border: Border.all(
                                                            color: AppColors
                                                                .azulCapenergy,
                                                          ),
                                                          borderRadius:
                                                          BorderRadius.all(
                                                              Radius.circular(
                                                                  15))),
                                                      child: Padding(
                                                        padding:
                                                        const EdgeInsets.all(8.0),
                                                        child: Image.network(
                                                          'https://.../agenda.png',
                                                          height: 25,
                                                        ),
                                                      ),

                                                    ),
                                                  ),
                                                ],
                                              ),
                                            ],
                                          ),
                                        ),

                                      ],
                                    ),
                                  ),
                                ),
                              );
                            },
                          );
                        }

                        return Image.asset(
                          "assets/images/vacio.png",
                          fit: BoxFit.contain,
                        );
                      },
                    ),
                  );
                },
              ),
            ),

Внутри дочернего элемента FutureBuilder я вызываю метод, заполняющий список:

fetchPacientes(value)

Как лучше всего реализовать RefreshIndicator в моем текущем приложении?


person mvasco    schedule 24.03.2021    source источник


Ответы (1)


Вот как я это делаю ..

Вам нужно будет создать отдельный StatefulWidget для своего ListView.Builder

class XYZ extends StatefulWidget {
  final filteredList;

  const XYZ(this.filteredList);
  @override
  _XYZState createState() => _XYZState();
}

class _XYZState extends State<XYZ> {
  var refreshfilteredList;

  @override
  Widget build(BuildContext context) {
    var filteredList = refreshfilteredList ?? widget.filteredList;

    return RefreshIndicator(
        onRefresh: () async {
          refreshfilteredList = await fetchPacientes(value);

          refreshfilteredList = refreshfilteredList
              .where((element) => (element.nombre_completo
                      .toLowerCase()
                      .contains(_controller.text.toLowerCase()) ||
                  element.NHC
                      .toLowerCase()
                      .contains(_controller.text.toLowerCase()) ||
                  element.apellidos
                      .toLowerCase()
                      .contains(_controller.text.toLowerCase())))
              .toList();
          setState(() {});
        },
        child: ListView.builder());
  }
}

Для реализации

 Expanded(
              child: Consumer(
                builder: (context, watch, child) {
                  var value = watch(clinicaIdStateProvider).state;

                  return Container(
                    child: FutureBuilder(
                      future: fetchPacientes(value),
                      builder: (context, snapshot) {

                        if (snapshot.hasData) {
                          var filteredList = snapshot.data;
                          print("a minusculas:"+_controller.text.toLowerCase());
                          filteredList = filteredList.where((element) => (
                              element.nombre_completo.toLowerCase().contains(_controller.text.toLowerCase()) ||
                                  element.NHC.toLowerCase().contains(_controller.text.toLowerCase()) ||
                                  element.apellidos.toLowerCase().contains(_controller.text.toLowerCase())
                          )).toList();

                          print("texto filtrado="+_controller.text.toLowerCase());


                          return XYZ(filteredList)
person thenoobslayer    schedule 24.03.2021
comment
Спасибо, но как в моем случае реализовать этот новый виджет внутри родительского класса? - person mvasco; 24.03.2021
comment
Я должен принять во внимание, что мне нужно передать также некоторые значения, чтобы он работал, например, значение переменной необходимо для фильтрации клиники пациентов и текста _controller.text для фильтрации списка для строки поиска - person mvasco; 24.03.2021
comment
@mvasco, я обновил свой ответ - person thenoobslayer; 24.03.2021
comment
Я не получаю, что это работает так, как вы предлагаете - person mvasco; 24.03.2021
comment
Я создал отдельный виджет XYZ, но отсутствуют ссылки на значение и _controller.text - person mvasco; 24.03.2021