![](/img/trans.png)
[英]Flutter: How to convert a stateful widget to a stateless widget and keep state changes
[英]Flutter how to change state of stateless widget
我正在 flutter 中創建一個 web 面板,並且我有一個無狀態小部件。 我只需要更改另一個文件上的 int 代表我的 fonts 的顏色正在改變。
main.dart
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primaryColor: Color(0xfff00B074),
textTheme: const TextTheme(
bodyText1: TextStyle(
fontSize: 18.0,
fontFamily: 'Barlow-Medium',
color: Color(0xff464255)),
),
),
home: MainScreen(),
);
}
}
main_screen.dart
class MainScreen extends StatelessWidget {
const MainScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Row(
children: [
if (Responsive.isDesktop(context))
Expanded(
// default flex = 1
child: SideMenu(),
),
Expanded(
flex: 5,
child: Container(),
),
],
),
),
);
}
}
還有我的側面菜單
class SideMenu extends StatelessWidget {
const SideMenu({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
children: [
Padding(
padding: const EdgeInsets.only(top: 30, bottom: 15),
child: SvgPicture.asset(
"assets/icon/logo.svg",
),
),
DrawerListTile(
intKey: 1,
title: "Dashboard",
svgSrc: "assets/icon/home_deactive.svg",
press: () {
sideMenuValue = 1;
print('asd');
},
),
DrawerListTile(
intKey: 2,
title: "Transaction",
svgSrc: "assets/icon/home_deactive.svg",
press: () {
sideMenuValue = 2;
},
),
DrawerListTile(
intKey: 3,
title: "Task",
svgSrc: "assets/icon/home_deactive.svg",
press: () {
sideMenuValue = 3;
},
),
DrawerListTile(
intKey: 4,
title: "Documents",
svgSrc: "assets/icon/home_deactive.svg",
press: () {
sideMenuValue = 4;
},
),
DrawerListTile(
intKey: 5,
title: "Store",
svgSrc: "assets/icon/home_deactive.svg",
press: () {
sideMenuValue = 5;
},
),
DrawerListTile(
intKey: 6,
title: "Notification",
svgSrc: "assets/icon/home_deactive.svg",
press: () {
sideMenuValue = 6;
},
),
DrawerListTile(
intKey: 7,
title: "Profile",
svgSrc: "assets/icon/home_deactive.svg",
press: () {},
),
DrawerListTile(
intKey: 8,
title: "Settings",
svgSrc: "assets/icon/home_deactive.svg",
press: () {},
),
],
),
);
}
}
class DrawerListTile extends StatelessWidget {
const DrawerListTile({
Key? key,
// For selecting those three line once press "Command+D"
required this.intKey,
required this.title,
required this.svgSrc,
required this.press,
}) : super(key: key);
final String title, svgSrc;
final VoidCallback press;
final int intKey;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: press,
child: Padding(
padding: const EdgeInsets.only(left: 30, bottom: 30),
child: Container(
child: Row(
children: [
SvgPicture.asset(
svgSrc,
height: 18,
),
SizedBox(
width: 13,
),
Text(
title,
style: sideMenuValue == intKey
? TextStyle(
fontSize: 18.0,
fontFamily: 'Barlow-Medium',
color: Color(0xfff00B074))
: Theme.of(context).textTheme.bodyText1,
),
],
)),
),
);
}
}
您可以在新聞上看到我正在更改 sideMenuValue 的值,該值沒有更改,因為我正在使用無狀態小部件並且不想使用有狀態小部件。
將需要更改模式的class更改如下
class HomePage extends StatefullWidget {
const HomePage({
Key? key,
}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<_HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
..........
);
}
請參考以下代碼
ValueNotifer 和 ValueListenableBuilder 可用於保存值並通過通知其偵聽器並減少重新構建小部件樹的次數來更新小部件。
main.dart文件
import 'package:elastic_search/SideMenu.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
/*
Since sideMenuValue is declared in main.dart file its available globally everywhere in the app
In order to update any value from other files we can make use of ValueNotifer
and to update widget we can use ValueListenableBuilder which updates the particular widget when the value changes (ValueNotifier value)
*/
final ValueNotifier sideMenuValue = ValueNotifier(0);
class MyApp extends StatelessWidget {
MyApp({Key key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primaryColor: Color(0xfff00B074),
textTheme: const TextTheme(
bodyText1: TextStyle(
fontSize: 18.0,
fontFamily: 'Barlow-Medium',
color: Color(0xff464255)),
),
),
home: MainScreen(),
);
}
}
class MainScreen extends StatelessWidget {
const MainScreen({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Row(
children: [
Expanded(
child: SideMenu(),
),
// Expanded(
// flex: 5,
// child: Container(),
// ),
],
),
),
);
}
}
SideMenu.dart 文件
import 'package:flutter/material.dart';
import 'package:elastic_search/main.dart';
class SideMenu extends StatelessWidget {
const SideMenu({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
children: [
// Padding(
// padding: const EdgeInsets.only(top: 30, bottom: 15),
// child: SvgPicture.asset(
// "assets/icon/logo.svg",
// ),
// ),
DrawerListTile(
intKey: 1,
title: "Dashboard",
svgSrc: "assets/icon/home_deactive.svg",
press: () {
sideMenuValue.value = 1;
print('asd');
},
),
DrawerListTile(
intKey: 2,
title: "Transaction",
svgSrc: "assets/icon/home_deactive.svg",
press: () {
sideMenuValue.value = 2;
},
),
DrawerListTile(
intKey: 3,
title: "Task",
svgSrc: "assets/icon/home_deactive.svg",
press: () {
sideMenuValue.value = 3;
},
),
DrawerListTile(
intKey: 4,
title: "Documents",
svgSrc: "assets/icon/home_deactive.svg",
press: () {
sideMenuValue.value = 4;
},
),
DrawerListTile(
intKey: 5,
title: "Store",
svgSrc: "assets/icon/home_deactive.svg",
press: () {
sideMenuValue.value = 5;
},
),
DrawerListTile(
intKey: 6,
title: "Notification",
svgSrc: "assets/icon/home_deactive.svg",
press: () {
sideMenuValue.value = 6;
},
),
DrawerListTile(
intKey: 7,
title: "Profile",
svgSrc: "assets/icon/home_deactive.svg",
press: () {
sideMenuValue.value = 7;
},
),
DrawerListTile(
intKey: 8,
title: "Settings",
svgSrc: "assets/icon/home_deactive.svg",
press: () {
sideMenuValue.value = 8;
},
),
],
),
);
}
}
class DrawerListTile extends StatelessWidget {
const DrawerListTile({
Key key,
// For selecting those three line once press "Command+D"
@required this.intKey,
@required this.title,
@required this.svgSrc,
@required this.press,
}) : super(key: key);
final String title, svgSrc;
final VoidCallback press;
final int intKey;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: press,
child: Padding(
padding: const EdgeInsets.only(left: 30, bottom: 30),
child: Container(
child: Row(
children: [
// SvgPicture.asset(
// svgSrc,
// height: 18,
// ),
SizedBox(
width: 13,
),
/*
In order update widget we can use ValueListenableBuilder which updates the particular widget when the value changes (ValueNotifier value)
*/
ValueListenableBuilder(
valueListenable: sideMenuValue,
builder: (context, snapshot, child) {
return Text(
title,
style: sideMenuValue.value == intKey
? TextStyle(
fontSize: 18.0,
fontFamily: 'Barlow-Medium',
color: Color(0xfff00B074))
: Theme.of(context).textTheme.bodyText1,
);
}),
],
)),
),
);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.