繁体   English   中英

Flutter 如何更改无状态小部件的 state

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM