Посмотрите на этот код - виджет для извлечения данных и отображения в списке:
class _MyEventsFragmentState extends State <MyEventsFragment>{
var events;
@override
initState(){
super.initState();
events = fetchEvents(true);
}
@override
Widget build(BuildContext context) {
return new Center(
child: FutureBuilder<EventsResponse>(
future: events,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
helpers.logout(context, Strings.msg_session_expired);
return CircularProgressIndicator();
}
return new Container(color: Colors.white,
child: new ListControl().build(snapshot));
}
return CircularProgressIndicator();
},
)
);
}
}
fetchEvent
метод имеет параметр, чтобы указать, какие события мне нужно выбрать. Если установлено значение true, - мои события, если установлено значение false - все события возвращаются. Выше кода загружает мои события и fetchEvents
вызывается внутри initState
переопределения, чтобы избежать ненужной перезагрузки данных.
Чтобы получить все события, я определил другой класс:
class EventsFragment extends StatefulWidget {
@override
_EventsFragmentState createState() => new _EventsFragmentState();
}
class _EventsFragmentState extends State <EventsFragment>{
var events;
@override
initState(){
super.initState();
events = fetchEvents(false);
}
@override
Widget build(BuildContext context) {
return new Center(
child: FutureBuilder<EventsResponse>(
future: events,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
helpers.logout(context, Strings.msg_session_expired);
return CircularProgressIndicator();
}
return new Container(color: Colors.white,
child: new ListControl().build(snapshot));
}
return CircularProgressIndicator();
},
)
);
}
}
Но это очень глупое решение, потому что код практически одинаков. Поэтому я попытался передать логическое значение, чтобы указать, какие события загружать, что-то вроде этого:
@override
initState(){
super.initState();
events = fetchEvents(isMyEvents);
}
isMyEvents
должен быть получен из EventsFragment
конструктора. Однако, это не будет доступно внутри initState
. Как пройти это правильно? Я мог получить к нему доступ внутри build
override, но не внутри initState
. Как правильно передать его и убедиться, что он будет обновляться при каждом создании экземпляра виджета?
[править]
Так вот как я решил свою проблему (вроде бы нормально):
class EventsFragment extends StatefulWidget {
const EventsFragment({Key key, this.isMyEvent}) : super(key: key);
final bool isMyEvent;
@override
_EventsFragmentState createState() => new _EventsFragmentState();
}
class _EventsFragmentState extends State <EventsFragment>{
var events;
@override
initState(){
super.initState();
events = fetchEvents(widget.isMyEvent);
}
@override
void didUpdateWidget(EventsFragment oldWidget) {
if(oldWidget.isMyEvent != widget.isMyEvent)
events = fetchEvents(widget.isMyEvent);
super.didUpdateWidget(oldWidget);
}
@override
Widget build(BuildContext context) {
return new Center(
child: FutureBuilder<EventsResponse>(
future: events,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
helpers.logout(context, Strings.msg_session_expired);
return CircularProgressIndicator();
}
return new Container(color: Colors.white,
child: new ListControl().build(snapshot));
}
return CircularProgressIndicator();
},
)
);
}
}