首页 > 解决方案 > 值更改后小部件宽度不更新

问题描述

我正在尝试构建一个侧面菜单,当按下下面屏幕截图中显示的垂直应用栏底部的箭头图标时,该菜单将打开和关闭。我目前正在通过使用名为 isleftWidgetCollapsed 的全局布尔值来执行此操作,如果 isleftWidgetCollapsed 设置为 true,它会将侧边菜单的宽度更改为 0。

它似乎工作正常,但只有当我调整应用程序窗口的大小时,如下面的屏幕截图所示。我怎样才能让它在按下 IconButton 时工作,而不必每次都调整应用程序窗口的大小?

在此处输入图像描述 在此处输入图像描述

buildLeftMenu.dart 中的代码部分:

Widget buildLeft(context, HomeViewModel model) {
  final _scrollbar = ScrollController();
  return Material(
    textStyle: TextStyle(
      color: Colors.white70,
      fontFamily: 'Lato',
    ),
    child: Row(
      children: [
        Container(
          width: (gb.isleftWidgetCollapsed==true)
              ? 0
              : MediaQuery.of(context).size.width * .20, //21.width,
          height: 100.height,
          decoration: BoxDecoration(
            color: MainTheme.primary[50], //Colors.blueAccent[400],
          ),
       

mainHomeView.dart 中的代码部分:

          body: Container(
            child: Row(
              children: [
                VerticalAppBar(),
                buildLeft(context, HomeViewModel()),
        ...

VerticalAppBar.dart 中的 onPressed 部分:


        leading: RotatedBox(
            quarterTurns: 1,
            child: IconButton(
              icon: Icon(gb.isleftWidgetCollapsed
                  ? Icons.arrow_right
                  : Icons.arrow_left),
              onPressed: () {
                setState(() {  
                  gb.isleftWidgetCollapsed = !gb.isleftWidgetCollapsed;
                  buildLeft(context, HomeViewModel());
                });
              },
            )),
      ),
    );
  }
}

globals.dart:

library my_prj.globals;

bool isLoggedIn = false;

bool isleftWidgetCollapsed = false;


标签: flutterdartstate-management

解决方案


buildLeft对inside的调用onPressed什么也不做:

onPressed: () {
  setState(() {  
    gb.isleftWidgetCollapsed = !gb.isleftWidgetCollapsed;
    buildLeft(context, HomeViewModel());
  });
},

这是使用hooks_riverpod包的解决方案。你可以在这里找到关于这个包的所有信息:http ://riverpod.dev/

在此处输入图像描述

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

void main() {
  runApp(
    ProviderScope(
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Flutter Demo',
        home: HomePage(),
      ),
    ),
  );
}

class HomePage extends HookWidget {
  @override
  Widget build(BuildContext context) {
    final menuOpened = useProvider(menuOpenedProvider).state;
    return Scaffold(
      body: Stack(
        children: [
          AnimatedPositioned(
            duration: Duration(milliseconds: 300),
            top: 0,
            right: 0,
            bottom: 0,
            left: menuOpened
                ? kVerticalBarWidth + kLeftMenuWidth
                : kVerticalBarWidth,
            child: Content(),
          ),
          AnimatedPositioned(
            duration: Duration(milliseconds: 300),
            top: 0,
            bottom: 0,
            left: menuOpened
                ? kVerticalBarWidth
                : kVerticalBarWidth - kLeftMenuWidth,
            child: LeftMenu(),
          ),
          Align(alignment: Alignment.centerLeft, child: VerticalAppBar()),
        ],
      ),
    );
  }
}

class VerticalAppBar extends HookWidget {
  @override
  Widget build(BuildContext context) {
    final menuOpened = useProvider(menuOpenedProvider).state;
    return Container(
      width: kVerticalBarWidth,
      color: kVerticalBarColor,
      child: Align(
        alignment: Alignment.bottomCenter,
        child: IconButton(
            onPressed: () =>
                context.read(menuOpenedProvider).state = !menuOpened,
            icon: Icon(menuOpened ? Icons.arrow_left : Icons.arrow_right)),
      ),
    );
  }
}

class LeftMenu extends HookWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: kLeftMenuColor,
      width: 200.0,
      padding: EdgeInsets.all(8.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          ...List.generate(20, (index) => Text('Menu Item $index')),
        ],
      ),
    );
  }
}

class Content extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: kContentColor,
      child: Center(
        child: Text('CONTENT'),
      ),
    );
  }
}

// Provider for the Menu State
final menuOpenedProvider = StateProvider((ref) => true);

// Some constants
const double kVerticalBarWidth = 48.0;
const double kLeftMenuWidth = 200.0;
const Color kVerticalBarColor = Color(0xffc19277);
const Color kLeftMenuColor = Color(0xffe1bc91);
const Color kContentColor = Color(0xff62959c);

推荐阅读