
// вся логика в этом классе
class HomeNotifier with ChangeNotifier {
HomeNotifier();
// флаг для первой картинки
bool _firstImageState = false;
bool get firstImageState => _firstImageState;
// флаг для второй картинки
bool _secondImageState = false;
bool get secondImageState => _secondImageState;
// изменение флага первой картинки
void changeFirstImageState() {
if (_firstImageState) {
return;
}
_firstImageState = true;
// оповещение об изменении
notifyListeners();
}
// изменение флага второй картинки
void changeSecondImageState() {
if (_secondImageState) {
return;
}
_secondImageState = true;
// оповещение об изменении
notifyListeners();
}
// сброс флагов картинок
void reset() {
_firstImageState = false;
_secondImageState = false;
// оповещение об изменении
notifyListeners();
}
}
// спец. вариант InheritedWidget
class HomeInheritedNotifier extends InheritedNotifier<HomeNotifier> {
const HomeInheritedNotifier(
{super.key, required super.notifier, required super.child});
static HomeNotifier _notifierOf(BuildContext context, [bool depend = true]) {
if (depend) {
return context
.dependOnInheritedWidgetOfExactType<HomeInheritedNotifier>()!
.notifier!;
} else {
return context
.getInheritedWidgetOfExactType<HomeInheritedNotifier>()!
.notifier!;
}
}
static bool firstImageStateOf(BuildContext context) =>
_notifierOf(context).firstImageState;
static bool secondImageStateOf(BuildContext context) =>
_notifierOf(context).secondImageState;
static VoidCallback changeFirstOf(BuildContext context) =>
_notifierOf(context, false).changeFirstImageState;
static VoidCallback changeSecondOf(BuildContext context) =>
_notifierOf(context, false).changeSecondImageState;
static VoidCallback resetOf(BuildContext context) =>
_notifierOf(context, false).reset;
}
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: HomeInheritedNotifier(
notifier: HomeNotifier(),
child: HomePage(),
),
),
);
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: [
SizedBox(
height: 50,
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
GestureDetector(
onTap: HomeInheritedNotifier.changeFirstOf(context),
child: HomeInheritedNotifier.firstImageStateOf(context)
? Image.asset('assets/happy.png')
: Image.asset('assets/bored.png'),
),
SizedBox(
width: 40,
),
GestureDetector(
onTap: HomeInheritedNotifier.changeSecondOf(context),
child: HomeInheritedNotifier.secondImageStateOf(context)
? Image.asset('assets/smile.png')
: Image.asset('assets/neutral.png'),
),
],
),
SizedBox(
height: 40,
),
TextButton(
onPressed: HomeInheritedNotifier.resetOf(context),
child: Text('Сбросить')),
],
),
),
);
}
}
Второй возможный вариант без использования InheritedNotifier
, но использованием ListenableBuilder
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: HomePage(
notifier: HomeNotifier(),
),
),
);
}
class HomePage extends StatelessWidget {
const HomePage({super.key, required this.notifier});
final HomeNotifier notifier;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: [
SizedBox(
height: 50,
),
Row(
mainAxisSize: MainAxisSize.min,
children: [
GestureDetector(
onTap: notifier.changeFirstImageState,
child: ListenableBuilder(
listenable: notifier,
builder: (context, child) => notifier.firstImageState
? Image.asset('assets/happy.png')
: Image.asset('assets/bored.png'),
)),
SizedBox(
width: 40,
),
GestureDetector(
onTap: notifier.changeSecondImageState,
child: ListenableBuilder(
listenable: notifier,
builder: (context, child) => notifier.secondImageState
? Image.asset('assets/smile.png')
: Image.asset('assets/neutral.png'),
),
),
],
),
SizedBox(
height: 40,
),
TextButton(
onPressed: notifier.reset,
child: Text('Сбросить'),
),
],
),
),
);
}
}