Flutter .of(context)
Егор Долгов · 02.08.2019This article was written for an older Flutter version and is being updated. Some code may not compile on the current version.
Для обращения к ближайшему родительскому объекту данного класса исходя из контекста, можно с помощью конструкции .of(context) .
В этом примере, на верхнем уровне у нас будет виджет TopScreen . Он будет задавать общий фон, но менять фон мы будем из дочернего виджета - по нажатию на одну из кнопок. Мы сможем обращаться к параметру TopScreen.of(context). color и к методу TopScreen.of(context).setState((){}) .
Описание классов TopScreen и TopScreenState
class TopScreen extends StatefulWidget {
final Widget child; // дочерний виджет
TopScreen({this.child});
@override
State createState() => _TopScreenState();
static _TopScreenState of(BuildContext context) {
// Эта конструкция нужна, чтобы можно было обращаться к нашему виджету
// через: TopScreen.of(context)
assert(context != null);
final _TopScreenState result =
context.ancestorStateOfType(const TypeMatcher<_TopScreenState>());
return result;
}
}
class _TopScreenState extends State {
Color _color = Colors.green; // цвет фона
@override
Widget build(BuildContext context) {
return Scaffold(
body: AnimatedContainer( // используем это виджет для анимации цвета фона
child: widget.child, // обращение к дочернему виджету TopScreen через widget.child
color: _color,
duration: Duration(milliseconds: 500), // длительность анимации
));
}
}
Остальная часть программы
import 'package:flutter_web/material.dart';
void main() => runApp(MaterialApp(home: TopScreen(child: MainScreen())));
class MainScreen extends StatefulWidget {
@override
State createState() => MainScreenState();
} //MainScreen
class MainScreenState extends State {
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
MaterialButton(
child: Text('red'),
color: Colors.red,
onPressed: () {
TopScreen.of(context)._color = Colors.red; // Изменяем цвет фона напрямую.
// ВНИМАНИЕ: Изменять параметр объекта напрямую не правильно для ООП!
// Это только пример, в реализации лучше сделать сеттер или метод для изменения.
TopScreen.of(context).setState(() {}); // Вызов метода смены состояния родительского виджета.
},
),
MaterialButton( // Все тоже самое что и для кнопки выше.
child: Text('green'),
color: Colors.green,
onPressed: () {
TopScreen.of(context)._color = Colors.green;
TopScreen.of(context).setState(() {});
},
),
MaterialButton( // Все тоже самое что и для кнопки выше.
child: Text('blue'),
color: Colors.blue,
onPressed: () {
TopScreen.of(context)._color = Colors.blue;
TopScreen.of(context).setState(() {});
},
),
],
),
);
} //build
} //MainScreenStat