Я пытаюсь создать кнопку-вкладку, в которой есть список (стек) на первой странице перехода. Почему-то есть эта ошибка, и я просто не могу понять, почему ...
Это мой домашний файл:
class Home extends StatelessWidget {
final AuthService _auth = AuthService();
@override
Widget build(BuildContext context) {
return TabContainerIndexedStack();
}}
Это TabContainerIndexStack ():
class TabContainerIndexedStack extends StatefulWidget {
TabContainerIndexedStack({Key key}) : super(key: key);
@override
_TabContainerIndexedStackState createState() =>
_TabContainerIndexedStackState();
}
class _TabContainerIndexedStackState extends State<TabContainerIndexedStack> {
int tabIndex = 0;
List<Widget> listScreens;
@override
void initState() {
super.initState();
listScreens = [
Tab1(),
Tab2(),
Tab3(),
];
}
// @override
// bool get wantKeepAlive =>
// true; //by default it will be null, change it to true.
@override
Widget build(BuildContext context) {
return MaterialApp(
color: Colors.yellow,
home: Scaffold(
body: IndexedStack(index: tabIndex, children: listScreens),
bottomNavigationBar: BottomNavigationBar(
currentIndex: tabIndex,
onTap: (int index) {
setState(() {
tabIndex = index;
});
},
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Tab1'),
),
BottomNavigationBarItem(
icon: Icon(Icons.report_problem),
title: Text('Tab2'),
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
title: Text('Tab3'),
),
]),
backgroundColor: Theme.of(context).primaryColor,
),
);
}
}
Это моя первая вкладка (другие работают !!!)
class Tab1 extends StatefulWidget {
@override
_Tab1State createState() => _Tab1State();
}
class _Tab1State extends State<Tab1> with AutomaticKeepAliveClientMixin<Tab1> {
@override
void initState() {
super.initState();
print('initState Tab1');
}
@override
Widget build(BuildContext context) {
print('build Tab1');
return Scaffold(
appBar: AppBar(
title: Text('Tab1'),
),
body: AuftraegeList()
);
}
@override
bool get wantKeepAlive => true;
}
Я думаю, что проблема тут же в "body: AuftraegeList (). .. "выше ..
Вот файл AuftraegeList ():
class AuftraegeList extends StatefulWidget {
@override
_AuftraegeListState createState() => _AuftraegeListState();
}
class _AuftraegeListState extends State<AuftraegeList> {
@override
Widget build(BuildContext context) {
final auftraege = Provider.of<List<Auftrag>>(context);
return ListView.builder(
itemCount: auftraege.length,
itemBuilder: (context, index){
return AuftragTile(auftrag: auftraege[index]);
},
);
}
}
Надеюсь, этого достаточно для решения моей проблемы. Я очень плохо знаком с Флаттером, поэтому было бы неплохо, если бы вы могли сказать, где именно я должен изменить ЧТО. Большое спасибо !!!
РЕДАКТИРОВАТЬ: Вот код моего home.dart, который представляет собой код, который представляет список в моем главном представлении.
class Home extends StatelessWidget {
final AuthService _auth = AuthService();
@override
Widget build(BuildContext context) {
return TabContainerIndexedStack();
/*
return StreamProvider<List<Auftrag>>.value(
value: DatabaseService().auftraege,
child: Scaffold(
bottomNavigationBar: btmBar(),
backgroundColor: Colors.blue[50],
appBar: AppBar(
title: Text('Home title'),
backgroundColor: Colors.blue,
elevation: 0.0,
actions: <Widget>[
FlatButton.icon(
icon: Icon(Icons.person),
label: Text('logout'),
onPressed: () async{
await _auth.signOut();
},
)
],
),
body: AuftraegeList(),
),
);
*/
}
}
(его часть, которую я закомментировал)
Спасибо !!
РЕДАКТИРОВАТЬ (2) !!!
Последнее редактирование:
Итак, мой первый класс касаний теперь выглядит следующим образом (я изменил в теле сборки Widget [] на databaseService.auftraege после того, как сначала объявил databaseService).
class Tab1 extends StatefulWidget {
@override
_Tab1State createState() => _Tab1State();
}
class _Tab1State extends State<Tab1> with AutomaticKeepAliveClientMixin<Tab1> {
// Where should I put this line? Whereever I put this, it gives me errors (already imported services/database.dart)
final DatabaseService databaseService = Provider.of<DatabaseService()>(context);
@override
void initState() {
super.initState();
print('initState Tab1');
}
@override
Widget build(BuildContext context) {
print('build Tab1');
return Scaffold(
appBar: AppBar(
title: Text('Tab1'),
),
body: Provider(
create: (context) => databaseService.auftraege,
child: AuftraegeList(),
)
);
}
@override
bool get wantKeepAlive => true;
}
Может быть, его также полезно показать Вы мои службы / база данных
class DatabaseService{
final String uid;
DatabaseService({ this.uid });
// collection reference
final CollectionReference auftraegeCollection = Firestore.instance.collection('auftraege');
Future updateUserData(String title, String info, int price, String user) async{
return await auftraegeCollection.document(uid).setData({
'title' : title,
'info': info,
'price': price,
'user': user,
});
}
List<Auftrag> _auftragListFromSnapshot(QuerySnapshot snapshot){
return snapshot.documents.map((doc){
return Auftrag(
title: doc.data['title']?? '',
info: doc.data['info']?? '',
price: doc.data['price']?? 0,
user: doc.data['user']?? '',
);
}).toList();
}
// get auftraege stream
Stream <List<Auftrag>> get auftraege {
return auftraegeCollection.snapshots()
.map(_auftragListFromSnapshot);
}
}
Когда оставляете такой код, выдает ошибку в этой строке:
final DatabaseService databaseService = Provider.of<DatabaseService()>(context);
в моем классе tab1.dart. В «контекстах» и «ошибка:« только элементы stati c могут быть доступны в инициализаторах »и« ошибка: выражение сравнения не может быть операндом другого выражения сравнения », а также« ошибка: оператор «<'isn» t определено для класса 'T Function (BuildContext, {listen: bool})'. "</p>
Может быть, вы знаете, что делать. Я думаю, что просто поставил эту строку не в том месте.
### EDIT (3) ### (Исключение)
═══════════════════════════════════════════════════════════════════════════════════════════════════════════════ ═════════════════════════════════════════════════ было сгенерировано следующее утверждение при создании _BodyBuilder: зависимостьOnInheritedWidgetOfExactType> () или depenOnInheritedElement () было вызвано до того, как _Tab1State.initState () завершено.
Когда изменяется унаследованный виджет, например, если изменяется значение Theme.of (), его зависимые виджеты перестраиваются. Если ссылка зависимого виджета на унаследованный виджет находится в конструкторе или методе initState (), то перестроенный зависимый виджет не будет отражать изменения в унаследованном виджете.
Обычно ссылки на унаследованные виджеты должны встречаться в виджете методы build (). В качестве альтернативы, инициализация на основе унаследованных виджетов может быть помещена в метод didChangeDependencies, который вызывается после initState и всякий раз, когда после этого изменяются зависимости.
Соответствующий виджет, вызывающий ошибки, был: Scaffold file: /// Users / xxxxxxxxxxxxxxx /AndroidStudioProjects/promi_prototype/lib/screens/home/tab_containter_indexedstack.dart:36:13 Когда было сгенерировано исключение, это был стек:
0 StatefulElement.dependOnInheritedElement. (пакет: flutter / src / widgets / framework.dart: 4467: 9)
1 StatefulElement.dependOnInheritedElement (пакет: flutter / src / widgets / framework.dart: 4510: 6)
2 StatefulElement.inheritFromElement (пакет: flutter / src / widgets / framework.dart: 4458: 12)
3 Element.inheritFromWidgetOfExactType (пакет: flutter / src / widgets / framework.dart: 3556: 14)
4 Provider.of (package: provider / src / provider.dart: 259: 19)
В нем указано, что соответствующий виджет, вызывающий ошибки, был: tab_containter_indexedstack.dart, я уже разместил этот код на самое начало моего поста. Симулятор теперь показывает только синий фон с панелью вкладок внизу. Нет текста на других вкладках (работал раньше) и нет предупреждения об ошибке на вкладке 1. Даже нет заголовков.
Привет !! :)
.
.
.
### EDIT (4) ###
Боже мой xD Извините за то, что не работает .. и СПАСИБО за помощь!
Позвольте мне начать сообщение об ошибке:
Следующее утверждение было выдано при построении Provider >> (dirty, state: flutter: _DelegateWidgetState # eb784): flutter: Пытался использовать Provider с подтипом Listenable / Stream (Stream>). flutter: flutter: Вероятно, это ошибка, поскольку провайдер не будет автоматически обновлять flutter зависимых: при обновлении Stream> Вместо этого рассмотрите возможность изменения Provider для более конкретной реализации flutter:, которая обрабатывает механизм обновления, такой как: flutter: flutter: - flutter ListenableProvider: - flutter ChangeNotifierProvider: - flutter ValueListenableProvider: - StreamProvider Соответствующий виджет, вызывающий ошибки, был: flutter: Provider> > flutter: file: ///Users/xxxxxxxxxxxx/AndroidStudioProjects/promi_prototype/lib/screens/my_tabs/tab1.dart: 33: 13
Таким образом, по-прежнему существует проблема с поставщиком в tab1. дротик. Мое предположение состояло в том, чтобы изменить функцию Provider в AuftragList (), потому что там я использовал «старый» способ, такой как Provider.of> (context), точно так же, как вы упомянули в редактировании 18 часов go.
Это то, что я сделал (закомментировано было раньше):
class AuftraegeList extends StatefulWidget {
@override
_AuftraegeListState createState() => _AuftraegeListState();
}
class _AuftraegeListState extends State<AuftraegeList> {
DatabaseService databaseService ;
@override
Widget build(BuildContext context) {
databaseService = Provider.of<DatabaseService>(context);
// final auftraege = Provider.of<List<Auftrag>>(context);
return ListView.builder(
// itemCount: auftraege.length,
// itemBuilder: (context, index){
itemCount: databaseService.length, //RED MARK HERE
itemBuilder: (context, index){
return AuftragTile(auftrag: databaseService[index]); //RED MARK HERE
},
);
}
}
Я думал, что теперь все в порядке, но я получаю красные отметки под ".lenght
" и под "[index]
». Компилятор говорит, что я должен создать геттер в файле helpers / database.dart, который я тогда пробовал. Но безуспешно. Тогда я удалил получатели.
У вас есть идея? Правильно ли менять объект Provider в AuftraegeList (), даже если компилятор сказал, что проблема в tap1.dart?
.