如何在另一个小部件中管理小部件状态

Posted

技术标签:

【中文标题】如何在另一个小部件中管理小部件状态【英文标题】: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: [])
          ],
        ),
      ),
    );
  

【问题讨论】:

试试这个来传递值并从其他小部件***.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 【参考方案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

【讨论】:

谢谢,我有点了解提供者如何通过一些阅读和实验工作,但这非常有效

以上是关于如何在另一个小部件中管理小部件状态的主要内容,如果未能解决你的问题,请参考以下文章

如何在另一个小部件更新qt中的相同内容后更新小部件内容

Android:如何使用 ConstraintLayout 在另一个小部件上显示一个小部件?

如何从另一个 dart 文件中调用有状态小部件(有表单)方法?- Flutter

Qt 在另一个小部件中调整小部件的大小

ListView flutter 中如何管理不同小部件的状态?

如何从有状态小部件类 Flutter 访问小部件状态