【问题标题】:How to manage a widget state in another widget如何在另一个小部件中管理小部件状态
【发布时间】:2021-09-28 06:04:27
【问题描述】:

我最近开始使用 Flutter 和 Flutter Web。从另一个文件(tables_display.dart)更改一个文件(content_table.dart)中的小部件状态的最佳做法是什么

tables_display.dart

import 'package:portal/components/content_table.dart';

class TableDisplay extends StatefulWidget {
  @override
  _TableDisplayState createState() => _TableDisplayState();
}

class _TableDisplayState extends State<TableDisplay> {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Container(
        padding: EdgeInsets.only(top: 8.0),
        width: MediaQuery.of(context).size.width,
        height: 700,
        decoration: BoxDecoration(),
        child: DefaultTabController(
          length: 3,
          initialIndex: 0,
          child: Column(
            children: [
              Align(
                alignment: Alignment.centerLeft,
                child: TabBar(
                  labelStyle:
                      TextStyle(fontSize: 12, fontWeight: FontWeight.w600),
                  isScrollable: true,
                  indicatorSize: TabBarIndicatorSize
                      .label, //make the indicator the same size as the label
                  labelPadding: EdgeInsets.fromLTRB(5, 0, 5, 0),
                  labelColor: FlutterFlowTheme.primaryColor,
                  unselectedLabelColor: Colors.black54,
                  indicatorColor: FlutterFlowTheme
                      .primaryColor, //adds color to the indicator
                  tabs: [
                    Container(
                      // decoration: BoxDecoration(
                      //   borderRadius: BorderRadius.circular(0),
                      //   border: Border(
                      //       top: BorderSide(width: 1, color: Colors.red),
                      //       left: BorderSide(width: 1, color: Colors.red),
                      //       right: BorderSide(width: 1, color: Colors.red)),
                      //   //border: Border.all(color: Colors.redAccent, width: 1)
                      // ),
                      child: Padding(
                        padding: const EdgeInsets.fromLTRB(25, 5, 25, 0),
                        child: Tab(
                          text: 'Easy',
                        ),
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.fromLTRB(25, 5, 25, 0),
                      child: Tab(
                        text: 'Medium',
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.fromLTRB(25, 5, 25, 0),
                      child: Tab(
                        text: 'Hard',
                      ),
                    ),
                  ],
                ),
              ),
              Expanded(
                  child: Container(
                // decoration: BoxDecoration(
                //     border: Border(
                //   top: BorderSide(width: 1, color: Colors.red),
                // )),

                color: Colors.white,
                child: Padding(
                  padding: const EdgeInsets.only(top: 0, bottom: 20),
                  child: TabBarView(
                    children: [
                      ContentTable(),
                      ContentTable(),
                      ContentTable(),
                    ],
                  ),
                ),
              )),
            ],
          ),
        ),
      ),
    );
  }
}

在上面的代码中,我创建了一个由 3 个选项卡组成的 DefaultTabController; Easy、Medium 和 Hard,每个选项卡都可以访问 content_table.dart 文件中的 ContentTable() 小部件 我希望当单击 SPECIFIC 选项卡时,它会使用指定的数据重建小部件树中的 ContentTable() 小部件。你会怎么做呢?

content_table.dart:

import 'package:flutter/material.dart';

class ContentTable extends StatefulWidget {
  @override
  _ContentState createState() => _ContentState();
}

class _ContentState extends State<ContentTable> {
  @override
  Widget build(BuildContext context) {
    return Container(
      //decoration: BoxDecoration(border: Border.all(color: Colors.grey[100])),
      child: Padding(
        padding: const EdgeInsets.all(0.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            DataTable(
                showCheckboxColumn: true,
                decoration: BoxDecoration(
                  border: Border(
                    top: BorderSide(color: Colors.grey[100], width: 1),
                    bottom: BorderSide(color: Colors.grey[100], width: 1),
                  ),
                ),
                headingRowColor: MaterialStateColor.resolveWith(
                    (states) => Colors.grey.shade50),
                columns: [
                  DataColumn(
                    label: Text("ID", style: TextStyle(fontSize: 11)),
                  ),
                  DataColumn(
                    label: Text("Question", style: TextStyle(fontSize: 11)),
                  ),
                  DataColumn(
                    label: Text("Opt. 1", style: TextStyle(fontSize: 11)),
                  ),
                  DataColumn(
                    label: Text("Opt. 2", style: TextStyle(fontSize: 11)),
                  ),
                  DataColumn(
                    label: Text("Opt. 3", style: TextStyle(fontSize: 11)),
                  ),
                  DataColumn(
                    label: Text("Opt. 4", style: TextStyle(fontSize: 11)),
                  ),
                  DataColumn(
                    label: Text("Explanation", style: TextStyle(fontSize: 11)),
                  ),
                  DataColumn(
                    label: Text("Image", style: TextStyle(fontSize: 11)),
                  ),
                ],
                rows: [])
          ],
        ),
      ),
    );
  }
}

【问题讨论】:

  • 试试这个来传递值并从其他小部件stackoverflow.com/a/68259836/2804581得到回调
  • that's call stateManagement try using provider / riverpod or any other package,也正如@DineshNagarajan所说,你可以使用callBack来完成小任务。
  • 我是 Flutter 新手,所以我不太了解小部件之间的数据或信息传递
  • 如前所述,provider 或 riverpod 是普遍接受的方法。这些库帮助您“提升状态”,即在小部件树中将相关状态存储在“更高”的小部件中,这是您希望能够连接的两个小部件的共同祖先。阅读更多:flutter.dev/docs/development/data-and-backend/state-mgmt/simple
  • 只需使用 GetX,您的问题正好有一个教程。 youtube.com/watch?v=RaqPIoJSTtI

标签: flutter dart flutter-web flutter-widget


【解决方案1】:

对于这个特定的问题,解决方案非常简单。在小部件之间传递数据与它们在哪些文件中定义无关,只与它们在您的应用程序中实际使用的位置有关。看起来您正在使用 ContentTable 作为 TableDisplay 的子小部件,因此您可以毫无问题地将信息传递给它。只需在 content_table.dart 中定义一个参数,并在您在 tables_display.dart 中调用 ContentTable 时为该参数提供一个值,例如:

content_table.dart

class ContentTable extends StatefulWidget {
  final bool hard;

  ContentTable(
    {this.hard = false}
  );

  @override
  _ContentState createState() => _ContentState();
}

class _ContentState extends State<ContentTable> {
  //...if(widget.hard) {...

tables_display.dart

//...
TabBarView(
  children: [
    ContentTable(hard: true), //hard will be true
    ContentTable(), //hard will remain false
    ContentTable(hard: true), //hard will be true
  ],
),
//...

如果您想在应用程序的完全不同部分使用的小部件之间传递数据,请使用Provider

【讨论】:

  • 谢谢,我有点了解提供者如何通过一些阅读和实验工作,但这非常有效
猜你喜欢
  • 1970-01-01
  • 2019-12-17
  • 2021-07-20
  • 2021-09-11
  • 2020-09-10
  • 1970-01-01
  • 1970-01-01
  • 2021-12-26
  • 2018-10-30
相关资源
最近更新 更多