Построитель потоков не загружает нужные данные при первой загрузке экрана, а затем работает как следует после смены вкладок: Flutter - PullRequest
0 голосов
/ 17 апреля 2020

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

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

Проблема 1:

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

Проблема 2:

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

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

Любая помощь по этому вопросу будет высоко оценена.

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

 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, но я не знаю, как реализовать это с помощью потокового компоновщика, и я не уверен, что это сработает.

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

Ответы [ 2 ]

0 голосов
/ 17 апреля 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);
 }

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

0 голосов
/ 17 апреля 2020

Вы пытались перевернуть свой 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();
    }


  }
     );
...