Конструктор потоков не загружает нужные данные при первой загрузке экрана, а затем работает должным образом после смены вкладок: Flutter

Я использую конструктор Stream для заполнения содержимого тела различных вкладок на экране с помощью Flutter. Конструктор потоков извлекает данные из Firebase и передает эти значения в разные списки, которые используются в построителе listView для отображения содержимого.

Вкладки на экране должны изменяться в зависимости от выбора на предыдущем экране. Эта часть работает хорошо. Тем не мение,

Проблема 1:

При начальной загрузке экрана содержимое всех вкладок отображается под вкладкой, которая была выбрана изначально. Только когда я смахиваю вправо один раз, то есть перехожу на другую вкладку, я получаю желаемое содержимое на экране, то есть соответствующее содержимое на соответствующих вкладках.

Проблема 2:

Если я вернусь с этого экрана на предыдущий и сделаю другой выбор, снова ... На первой вкладке, которая открывается на этом экране, я получаю содержимое предыдущей вкладки, которая была загружена до нажатия кнопки возврата. Только когда выбрана другая вкладка, я получаю желаемый результат.

Это означает, что написанный код работает, но только при определенных условиях. Вкладки загружаются точно так, как ожидалось, даже с первой попытки, только содержимое под вкладкой является проблемой ... и это тоже только на первом экране загрузки. Это явно означает, что что-то не так с построителем потока, но я не могу понять, что именно.

Любая помощь по этому поводу будет принята с благодарностью.

Макет моего кода с использованием построителя потоков:

 body : StreamBuilder(

  stream: Firestore.instance
          . //Required Reference//     
          .snapshots(),

  builder: (BuildContext context, AsyncSnapshot <QuerySnapshot>snapshot) {

    var someData = snapshot.data.documents;
    List<dynamic> someDocs = someData;

    if (snapshot.hasData == null){
      return CircularProgressIndicator(),}


    else if (snapshot.data.documents.length > 0){ 

      RequiredList1 = [];
      ..... More such statements ..........
      RequiredList11 = [];

      for(int i =0; i < someDocs.length; i++){

        RequiredList1.add(someData[i]['field1']);
        ....... More such calls ................
        RequiredList11.add(someData[i][field11']);            

      } 
       return WidgetToShowContents

       }
      }
     );

Единственное, что примечательно, это то, что сделанная ссылка включает имя вкладки, которая выбрана в данный момент. Однако, поскольку вкладка отображается правильно, и все остальные вкладки тоже работают, я уверен, что проблема не в этом.

Я подумал об использовании метода dispose, чтобы избавиться от построителя потока для решения проблемы 2, но я понятия не имею, как реализовать это с помощью построителя потока, и я не уверен, что это сработает.

Пожалуйста, поделитесь всеми имеющимися у вас знаниями, которые могут помочь в решении этой проблемы. Ваше здоровье!


person Chirag Rajgariah    schedule 16.04.2020    source источник


Ответы (2)


Вы пробовали перевернуть StreamBuilder на голову, я знаю, что это швы, как будто это может не иметь значения, но я видел, как это имеет значение, дайте мне знать, помогло ли это.

StreamBuilder(

  stream: Firestore.instance
          . //Required Reference//     
          .snapshots(),

  builder: (BuildContext context, AsyncSnapshot <QuerySnapshot>snapshot) {


    if (snapshot.hasData){
      if(snapshot.data.documents.length > 0){
 var someData = snapshot.data.documents;
    List<dynamic> someDocs = someData;

         RequiredList1 = [];
      ..... More such statements ..........
      RequiredList11 = [];

      for(int i =0; i < someDocs.length; i++){

        RequiredList1.add(someData[i]['field1']);
        ....... More such calls ................
        RequiredList11.add(someData[i]['field11']);            

      } 

      }else{
           return WidgetToShowContents
      }


    }else{
      CircularProgressIndicator();
    }


  }
     );
person wcyankees424    schedule 16.04.2020
comment
К сожалению, это ничего не меняет. Думаю, это могло бы помочь в некоторых других вещах. Есть ли у вас какие-нибудь другие идеи, которые я мог бы использовать, чтобы избавиться от этой проблемы? Спасибо! :) - person Chirag Rajgariah; 17.04.2020

Итак, после долгой отладки я понял, в чем причина того, что желаемое содержимое не получалось в теле при загрузке первой вкладки, а во всех последующих.

Единственное, что примечательно, это то, что сделанная ссылка включает имя вкладки, которая выбрана в данный момент. Однако, поскольку вкладка отображается правильно, и все остальные вкладки тоже работают, я уверен, что проблема не в этом.

Что я делал, так это то, что вызов ссылки зависел от значения на выбранной в данный момент вкладке, т.е. для разных вкладок были извлечены и отображены разные данные.

 @override
   void initState() {
   super.initState();    
  tabController = TabController(length: subCategoryList.length, vsync: this, initialIndex: 0);
  tabController.addListener(_setActiveTabIndex);
}

void _setActiveTabIndex() {
  activeTabIndex = tabController.index;
  setState(() {
    currentTab = subCategoryList[activeTabIndex].toString(); 
  });
}

Теперь я инициализировал tabController в initState () и использовал слушателя, чтобы узнать, какая вкладка в данный момент активна. При печати этих значений я узнал, что при первой загрузке экрана activeTabIndex, а также currentTab возвращают нулевые значения. Так было, когда либо загружался второй экран в первый раз, либо возвращался на первый экран и выбирал другой вариант, чтобы снова вернуться на этот экран.

В результате он возвращал желаемые значения в содержимом всякий раз, когда выбиралась другая вкладка, кроме первой.

Чтобы решить эту проблему, я установил значение по умолчанию для currentTab, чтобы всегда загружать содержимое на основе первой вкладки, которая будет отображаться при загрузке страницы. Я сделал это, добавив строку в initState () как:

  @override
   void initState() {
   super.initState(); 

  currentTab = subCategoryList[0].toString();
  tabController = TabController(length: subCategoryList.length, vsync: this, initialIndex: 0);
  tabController.addListener(_setActiveTabIndex);
 }

И теперь, когда страница загружается, я получаю желаемое содержимое в теле, так как значения уже были инициализированы к моменту создания виджета для отображения содержимого.

person Chirag Rajgariah    schedule 17.04.2020