Как мне обновить список из firestore, используя провайдера таким образом, чтобы он не перестраивался при использовании интерфейса? - PullRequest
0 голосов
/ 11 апреля 2020

Я довольно плохо знаком с трепетом и дротиком, поэтому заранее прошу прощения за глупости, которые я могу сказать.

Я создаю небольшое приложение, которое в основном отображает таблицу из пожарного магазина и переходит на страницу викторины на pu sh.

Кроме того, есть еще две вкладки, которые отображают другую информацию. Все обернуто в индексированном стеке, наслаждаясь общей нижней навигацией.

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

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

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

Вот код, иллюстрирующий мою проблему: Home.dart:

FirebaseUser loggedInUser;
enum TabItem { homeTable, annexe, favourite, translator }


class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  String userId;
  final FirebaseAuth auth = FirebaseAuth.instance;
  int _selectedIndex = 0;

  Map<TabItem, GlobalKey<NavigatorState>> navkeys = {
    TabItem.homeTable: GlobalKey<NavigatorState>(),
    TabItem.annexe: GlobalKey<NavigatorState>(),
    TabItem.favourite: GlobalKey<NavigatorState>(),
  };

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

  getUserRef() async {
    final FirebaseUser user = await auth.currentUser();
    final uid = user.uid;

    setState(() {
      userId = user.uid;
    });
  }

  @override
  Widget build(BuildContext context) {
    return CupertinoTabScaffold(
        tabBar:  CupertinoTabBar(
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.library_books),
                title: Text('Home'),
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.list),
                title: Text('Annexe'),
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.star),
                title: Text('Favourite'),
              ),
            ],
            activeColor: Colors.orange,
            onTap: (val) => _onTap(val, context),
            currentIndex: _selectedIndex) ,


        tabBuilder: (BuildContext context, int index) {
          return CupertinoTabView(builder: (BuildContext context) {
            return CupertinoPageScaffold(
              child: IndexedStack(index: _selectedIndex, children: <Widget>[            
                  Navigator(
                  key: navkeys['homeTable'],
                  onGenerateRoute: (route) => MaterialPageRoute(
                    settings: route,
                    builder: (context) => HomeTable(),
                  ),
                ),               
                Navigator(
                  key: navkeys['annexe'],
                  onGenerateRoute: (route) => MaterialPageRoute(
                    settings: route,
                    builder: (context) => Annexe(),
                  ),
                ),
                Navigator(
                  key: navkeys['favourite'],
                  onGenerateRoute: (route) => MaterialPageRoute(
                    settings: route,
                    builder: (context) => Memoire(),
                  ),
                ),
              ]),
            );
          });
        });
  } 

Из класса HomeTable (), где находится моя таблица I pu sh, на новую страницу, которая MyQuiz. На этой странице я в настоящее время беру данные из firestore, используя провайдера, затем изменяю список и затем отображаю его.

class MyQuiz extends StatefulWidget {
  final String difficulty ;
  final int indexFirstWord;
  final int indexLastWord;
  MyQuiz({
    this.difficulty,
    this.indexFirstWord,
    this.indexLastWord,
  });



  @override
  _MyQuizState createState() => _MyQuizState();
}

class _MyQuizState extends State<MyQuiz>   {
   @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    int start = widget.indexFirstWord;
    int end = widget.indexLastWord;
    final db = DatabaseServiceQuiz(start, end);

    return WillPopScope(
        onWillPop: _onBackPressed,
        child: Scaffold(
          body: SingleChildScrollView(
            child: Column(
              children: <Widget>[
                StreamProvider<List<Words>>.value(
                  value:  db.streamWord(),
                    child: Container(
                    height: MediaQuery.of(context).size.height,

                      child: Entire(),     
                  ),
                ),
              ],
            ),
          ),
        ));
  }
} 

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

class Entire extends StatefulWidget {
 @override
  _EntireState createState() => _EntireState();
}

class _EntireState extends State<Entire>  {

  @override
  Widget build(BuildContext context) {
    final _wordsback = Provider.of<List<Words>>(context);

//Here I do the suffling and randomization


return quizwidget();

Мой класс базы данных выглядит следующим образом :

class DatabaseServiceQuiz {
  DatabaseServiceQuiz(this.start, this.end);
  final Firestore _db = Firestore.instance;
  int start;
  int end;

  Stream<List<Words>> streamWord() {
    var ref = _db
        .collection('words')
        .orderBy('index')
        .where('index')
        .startAt([start]).endAt([end]);

    return ref.snapshots().map((list) =>
        list.documents.map((doc) => Words.fromFirestore(doc)).toList());    
  }
}

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

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