Automatycznie odświeżająca się lista

Automatycznie odświeżająca się lista
KK
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 30
1

Stworzyłem listę obiektów gdzie można dodawać lub usuwać je z różnych klas. Jest jedna statyczna lista którą wyświetlam. I potrzebuje żeby każda zmiana od razu odświeżyła widok listy.

Riddle
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10231
0

Cześć @Kazik Kowalski! 👋

Miło że jesteś na forum!

Kazik Kowalski napisał(a):

Stworzyłem listę obiektów gdzie można dodawać lub usuwać je z różnych klas. Jest jedna statyczna lista którą wyświetlam. I potrzebuje żeby każda zmiana od razu odświeżyła widok listy.

Pokaż kod jaki już napisałeś 😊

KK
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 30
1
Kopiuj
class ListPage extends StatefulWidget {
  const ListPage({super.key});

  @override
  State<ListPage> createState() => _ListPageState();
}

class _ListPageState extends State<ListPage> {

  void _navigateDetails(ListItem item) => GoRouter.of(context).go('/itemslist/itemdetails', extra: item);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: RefreshIndicator(
        color: const Color(0xFFFF4B4B),
        backgroundColor: const Color(0xFF26262A),
        onRefresh: () async {
          await Future.delayed(const Duration(seconds: 1));
          setState(() {});
        },
        child: ListView.builder(
          itemCount: MainModel.user.list.length,
          itemBuilder: (context, index) {
            final listItem = MainModel.user.list.elementAt(index);
            return SizedBox(
              height: 40,
              child: Row(
                children: [
                  Text(item.elapsedTime.inSeconds.toString()),
                  ElevatedButton(onPressed: () {_navigateDetails(listItem);}, child: const Text('Details'))
                ],
              ),
            );
          }
        ),
      )
    );
  }
}
GO
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 358
0

Powinieneś użyć setState() gdzie zmiana wartości ci odświeży cały widok automatycznie, tak ogólnie nie znam fluttera to ci nie powiem dokładnie jak to zrobić, jeśli zmodyfikujesz listę przez setState to ci się widok zaktualizuje po wykonaniu funkcji aktualizującej listę.

Pewnie da się to ręcznie też zrobić jak we frameworkach javascript typu react, gdzie ręcznie rerender gałęzi drzewa idzie zrobić, ale setState, po wykonaniu swojej funkcji wywołuje wewnętrzną funkcję rerenderowania, którą pójdzie namierzyć i potem jakoś w inny sposób wywołać jak się zagłębisz bardziej w to jak to działa. Ja akurat nie znam fluttera i nie wiem jak jedynie przez chatGPT mógłbym ci wygenerować jakiś kod, a pytałeś się chatGPT jak to rozwiązać bo to zaraz po wyszukiwarce w internecie następne miejsce do szukania odpowiedzi.

KK
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 30
0
.GodOfCode. napisał(a):

Powinieneś użyć setState() gdzie zmiana wartości ci odświeży cały widok automatycznie, tak ogólnie nie znam fluttera to ci nie powiem dokładnie jak to zrobić, jeśli zmodyfikujesz listę przez setState to ci się widok zaktualizuje po wykonaniu funkcji aktualizującej listę.

Pewnie da się to ręcznie też zrobić jak we frameworkach javascript typu react, gdzie ręcznie rerender gałęzi drzewa idzie zrobić, ale setState, po wykonaniu swojej funkcji wywołuje wewnętrzną funkcję rerenderowania, którą pójdzie namierzyć i potem jakoś w inny sposób wywołać jak się zagłębisz bardziej w to jak to działa. Ja akurat nie znam fluttera i nie wiem jak jedynie przez chatGPT mógłbym ci wygenerować jakiś kod, a pytałeś się chatGPT jak to rozwiązać bo to zaraz po wyszukiwarce w internecie następne miejsce do szukania odpowiedzi.

problem w tym że nie chec ręcznie odśwież. Czasem potrzebuje uŻyć metoedy w której jest metoda która jest w klasie która nie jest wigetem i nie mogę dam użyć setState po to metoda z StatefilWidget. Myślałem i czymś w stylu ObservableCollection jak w .net. Ale nie znalazłem odpowiednika

GO
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 358
0

Podasz jedną linijkę kodu, którą chcesz wykonać, z automatycznym rerenderingiem?

KK
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 30
1
.GodOfCode. napisał(a):

Podasz jedną linijkę kodu, którą chcesz wykonać, z automatycznym rerenderingiem?

Potrzebuje automatycznego odświeżania ui po dodaniu lub usinięciu elementu więc oto dwie linijki po których ui powinno zostać odświeżone: MainModel.user.list.add(item) lub MainModel.user.list.remove(MainModel.user.items.firstWhere((i) => i.id == id))

AdamWox
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Jastrzębie-Zdrój
  • Postów: 2180
0

To, że masz Add po stronie modelu nie znaczy, że się samo doda po stronie UI. Gdzie masz guzik z dodawaniem? W kodzie, który pokazałeś nie ma w ogóle takiej funkcjonalności, a piszesz o problemie odświeżania listy 🤔

KK
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 30
0
AdamWox napisał(a):

To, że masz Add po stronie modelu nie znaczy, że się samo doda po stronie UI. Gdzie masz guzik z dodawaniem? W kodzie, który pokazałeś nie ma w ogóle takiej funkcjonalności, a piszesz o problemie odświeżania listy 🤔

jest w innej klasie

AdamWox
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Jastrzębie-Zdrój
  • Postów: 2180
0

No spoko, kumam to, ale musisz jakąś akcje z UI wysłać 🤔 jak chcesz coś dodać nie klikając palcem na ekranie?

Riddle
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10231
0
Kazik Kowalski napisał(a):
.GodOfCode. napisał(a):

Podasz jedną linijkę kodu, którą chcesz wykonać, z automatycznym rerenderingiem?

Potrzebuje automatycznego odświeżania ui po dodaniu lub usinięciu elementu więc oto dwie linijki po których ui powinno zostać odświeżone: MainModel.user.list.add(item) lub MainModel.user.list.remove(MainModel.user.items.firstWhere((i) => i.id == id))

Dobry problem do rozwiązania, i myślę że rozwiązanie jest tylko jedno - polimorfizm. W jakiś sposób Twoja część modelu musi wywołać kod w UI, żeby go odświeżyć. Kontrola przepływu musi iść model -> ui (alternatywa to jest polling, czyli UI co jakiś interwał sprawdza stan modelu i sam się odświeża, ale to jest słabe).

Normalnie wymagałoby to użycia kodu UI w modelu, gdyby nie dobrodziejstwa polimorfizmu. Dodaj polimorifczny kod w modelu który woła UI, np. ui.removeItemFromList(2) albo ui.syncListTo(list). Model nie musi wiedzieć dokładnie czy UI jest we flutterze, czy czymkolwiem innym.

Oczywiście znaczy to że musisz najpierw wywołać operację na modelu (żeby zrobić zmiane), a potem na UI (żeby odświeżyć UI), to jest niestety konieczne. Ale możesz to opakować w dodatkową klasę, na której zrobisz np. .remove(), .add(), etc. i ta opakowujaca klasa zaktualizuje model i UI; czyli dokładnie to co ObservableList robi.

KK
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 30
0
Kopiuj
//inna klasa w której lista nie jest wyświetlana

  void _saveItem()
  {
    _item.id = MainModel.generateId();
    MainModel.user.list.add(_item);
    GoRouter.of(context).pop(true);
  }

  void _dontSave() async => GoRouter.of(context).pop(true);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Save Item"),
        ),
      body: Column(
        children: [
          Text( 
            _item.title.toString()
          ),
          ElevatedButton(
            onPressed: _dontSave, 
            child: const Text(
            "Delete item"
            )
          ),

          ElevatedButton(
            onPressed: _saveItem, 
            child: const Text(
            "Save item"
            )
          )
        ],
      ),
    );
  }
AdamWox
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Jastrzębie-Zdrój
  • Postów: 2180
0

Zamiast RefreshIndicator opakuj to w PopScope i tam zrób refresh listy itemów

Kopiuj
PopScope(
  canPop: false,
  onPopInvoked : (didPop){
   // logic
  },
)

parametr didPop bierze się z GoRouter.of(context).pop(true);

KK
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 30
0
AdamWox napisał(a):

Zamiast RefreshIndicator opakuj to w PopScope i tam zrób refresh listy itemów

Kopiuj
PopScope(
  canPop: false,
  onPopInvoked : (didPop){
   // logic
  },
)

parametr didPop bierze się z GoRouter.of(context).pop(true);

Rozumiem że wystarczy wywołać tam setState puste w środku żeby widok się odświerzył? Jeśli tak to nie pomogło

AdamWox
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Jastrzębie-Zdrój
  • Postów: 2180
0

A działało przy RefreshIndicator? Jeśli nie to pewnie ci się żaden item nie dodaje do listy, albo ją resetujesz. Debuguj, zrób sobie jakieś "print()" w odpowiednich miejscach i sprawdzaj co się pokazuje w konsoli. Pokaż też co robisz w MainModel.user.list.add(_item);

KK
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 30
0
AdamWox napisał(a):

A działało przy RefreshIndicator? Jeśli nie to pewnie ci się żaden item nie dodaje do listy, albo ją resetujesz. Debuguj, zrób sobie jakieś "print()" w odpowiednich miejscach i sprawdzaj co się pokazuje w konsoli. Pokaż też co robisz w MainModel.user.list.add(_item);

Działało. Dodam jeszcze że do nawigacji używam StatefulShellRoute jak by miało to coś zmienić. MainModel.user.list.add(_item); - to jest klasa w której jest statyczna instancja klasy User która ma statyczną listę gdzie jest wywołana podstawowa metoda add która jest wbudowana w język więc nie czego tu pokazywać.

AdamWox
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Jastrzębie-Zdrój
  • Postów: 2180
0

No to już nie wiem jak mam pomóc. Tutaj masz przykład z dokumentacji jak to jest zrobione z PopScope
PopScope class

KK
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 30
0

A może wie ktoś jak wykonać metodę na stronie za każdym razem gdy user do niej nawiguje?

KO
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Miasto Spotkań
  • Postów: 34
0

Zapewne przyda sie initState. Jak nawigujesz do strony to ona się wtedy tworzy i wywołać w tej metodzie możesz jakiś kod który inicjalizuje wszystko. Poczytaj proszę jak używać bloca. On separuję logikę od interfejsu na zasadzie event z interfejsu -> metoda w blocu która reaguje na event -> bloc robi update State i interfejs się zmienia wtedy.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.