Flutter——StateFulWidget有状态组件

166 阅读3分钟
  • 有状态组件

页面中想要修改数据需要用到这个类。
StatefulWidget 配合setState(() { _numsum++; }); 实现数据的动态
class MyBody extends StatefulWidget {
  const MyBody({super.key});

  @override
  State<MyBody> createState() => _MyBodyState();
}

class _MyBodyState extends State<MyBody> {
  int _numsum = 0;
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text(
            "$_numsum",
            style: const TextStyle(color: Colors.red),
          ),
          ElevatedButton(
              onPressed: () {
                setState(() {
                  _numsum++;
                });

              },
              child: const Text("增加"))
        ],
      ),
    );
  }
}

**动态增加列表** floatingActionButton 默认右下角
       

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ScreenUtilInit(
        designSize: Size(750, 1252),
        builder: (context, child) {
          return MaterialApp(
            builder: (context, child) {
              return MediaQuery(
                  data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
                  child: child!);
            },
            theme: ThemeData(primarySwatch: Colors.blue),
            home: const HomePage(),
          );
        });
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final List<String> _list = [];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Flutter App"),
      ),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.add),
        onPressed: () {
          setState(() {
            _list.add("我是一个新增列表");
          });
        },
      ),
      body: ListView(
          children: _list.map((v) {
        return ListTile(
          title: Text(v),
        );
      }).toList()),
    );
  }
}


  • BottomNavigationBar实现页面切换

    iconSize 底部菜单大小 fixedColor: Colors.red, 选中的颜色 onTap 点击菜单事件 items 设置菜单个数 currentInde 第几个菜单选中 type: BottomNavigationBarType.fixed 4个菜单以上的配置
tabs 文件
class Tabs extends StatefulWidget {
  const Tabs({super.key});

  @override
  State<Tabs> createState() => _TabsState();
}

class _TabsState extends State<Tabs> {
  int _currentIndex = 0;
  final List<Widget> _pages = const [HomePage(), SettingPage(), CategoryPage()];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("您好!"),
      ),
      body: _pages[_currentIndex],
      bottomNavigationBar: BottomNavigationBar(
          onTap: (v) {
            setState(() {
              _currentIndex = v;
            });
          },
          currentIndex: _currentIndex,
          items: const [
            BottomNavigationBarItem(icon: Icon(Icons.home), label: "首页"),
            BottomNavigationBarItem(icon: Icon(Icons.category), label: "分类"),
            BottomNavigationBarItem(icon: Icon(Icons.settings), label: "设置"),
          ]),
    );
  }
}

main文件

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import './pages/tabs.dart';
void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ScreenUtilInit(
        designSize: Size(750, 1252),
        builder: (context, child) {
          return MaterialApp(
            builder: (context, child) {
              return MediaQuery(
                  data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
                  child: child!);
            },
            theme: ThemeData(primarySwatch: Colors.blue),
            home: const HomePage(),
          );
        });
  }
}

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return const Tabs();
  }
}

可以floatingActionButton 使用实现咸鱼中间突起按钮
floatingActionButtonLocation 按钮位置
backgroundColor  背景颜色

 floatingActionButton: Container(
        width: 60,
        height: 60,
        padding: const EdgeInsets.all(3),
        margin: const EdgeInsets.only(top: 6),
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.circular(30),
        ),
        child: FloatingActionButton(
          backgroundColor: _currentIndex == 2 ? Colors.red : Colors.blue,
          child: const Icon(Icons.add),
          onPressed: () {
            setState(() {
              _currentIndex = 2;
            });
          },
        ),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,

  • 全局配置按钮点击时去掉波纹

    splashColor: Colors.transparent, highlightColor: Colors.transparent,
MaterialApp(
            builder: (context, child) {
              return MediaQuery(
                  data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
                  child: child!);
            },
            theme: ThemeData(
              splashColor: Colors.transparent,
              highlightColor: Colors.transparent,
              primarySwatch: Colors.blue,
              // buttonTheme: const ButtonThemeData(
              //     highlightColor: Colors.transparent,
              //     splashColor: Colors.transparent),
              // bottomNavigationBarTheme:
              //     const BottomNavigationBarThemeData(elevation: 0)
            ),
            home: const HomePage(),
          );
  • 抽屉组件 左侧drawere 右侧ndDrawer

DrawerHeader()自定义抽屉头部
Container(
                      child: DrawerHeader(
                          decoration: const BoxDecoration(
                              image: DecorationImage(
                                  image: NetworkImage(
                                      "https://www.itying.com/images/flutter/2.png"),
                                  fit: BoxFit.cover)),
                          child: ListView(
                            children: const [
                              ListTile(
                                leading: CircleAvatar(
                                  backgroundImage: NetworkImage(
                                      "https://www.itying.com/images/flutter/3.png"),
                                ),
                                title: Text(
                                  "张三王五",
                                  style: TextStyle(color: Colors.red),
                                ),
                              ),
                              ListTile(
                                title: Text("邮箱654393397@qq.com"),
                              ),
                              ListTile(
                                title: Text("个性签名:开个马自达怪不得你塞车",
                                    style: TextStyle(color: Colors.red)),
                              ),
                            ],
                          )),
                    )
  • UserAccountsDrawerHeader 抽屉头部

accountName  //名字
accountEmail //邮箱
currentAccountPicture  // 当前用户头像
CircleAvatar  //圆形头像
otherAccountsPictures  //其他用户头像
  • AppBar 样式定义

class _HomePageState extends State<HomePage> //先混入SingleTickerProviderStateMixin,然后定义TabController
    with SingleTickerProviderStateMixin {
  late TabController _tabController;
    leading //左侧按钮
    title //标题
    backgroundColor //背景色
    actions //右侧属性
    bottom: TabBar(
    controller: _tabController //设置切换
    tabs:[]  //装切换的菜单
    isScrollable: true //是否可以滑动
    indicatorColor: Colors.yellow,  //指示器颜色
    indicatorWeight: 2,  下划线的厚重度
    indicatorPadding: const EdgeInsets.all(5), //内边距
    indicatorSize: TabBarIndicatorSize.label //下划线样式与文字等长
    indicator: BoxDecoration()  //盒子样式
    labelColor:Colors.black //tab文字颜色
    unselectedLabelColor //未选中label颜色
    onTap: (index){ //只能监听点击事件
                  print(index);  //tab索引
                },
    _tabController.addListener(() {  //通过监听拿到索引
      if(_tabController.animation!.value == _tabController.index){
        print(_tabController.index);
      }
    });
    centerTitle: true  //文字居中
    )
    //配合切换时显示页面  **TabBarView**
     body: TabBarView(controller: _tabController, children: [
        ListView(
          children: const [
            ListTile(
              title: Text("关注列表"),
            )
          ],
        ),
    //PreferredSize  可以配置appBar的高度
    PreferredSize(
        preferredSize: const Size.fromHeight(100),
        child: AppBar())
//组件销毁触发
  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    _tabController.dispose();
  }
  • 自定义缓存组件KeepAliveWrapper

import 'package:flutter/material.dart';

class KeepAliveWrapper extends StatefulWidget {
  const KeepAliveWrapper(
      {super.key, required this.child, this.keepAlive = true});
  final Widget? child;
  final bool keepAlive;
  @override
  State<KeepAliveWrapper> createState() => _KeepAliveWrapperState();
}

class _KeepAliveWrapperState extends State<KeepAliveWrapper>
    with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) {
    return widget.child!;
  }

  @override
  bool get wantKeepAlive => widget.keepAlive;

  @override
  void didUpdateWidget(covariant KeepAliveWrapper oldWidget) {
    if (oldWidget.keepAlive != widget.keepAlive) {
      updateKeepAlive();
    }
    super.didUpdateWidget(oldWidget);
  }
}