Geddez
Geddez

Reputation: 41

How to manage a widget state in another widget

I have recently started working with flutter and flutter web. What is best practice to change state of a widget which is in one file (content_table.dart) from another file (tables_display.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(),
                    ],
                  ),
                ),
              )),
            ],
          ),
        ),
      ),
    );
  }
}

In above code, I have created a DefaultTabController which is made up of 3 tabs; Easy, Medium and Hard, each of the tabs have access to ContentTable() widget that's in the content_table.dart file I want that when a SPECIFIC tab is clicked it rebuilds the ContentTable() widget in the widget tree with data specified. How would you go about that?

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: [])
          ],
        ),
      ),
    );
  }
}

Upvotes: 0

Views: 1595

Answers (1)

PatrickMahomes
PatrickMahomes

Reputation: 944

For this particular issue, the solution is very simple. Passing data between widgets has nothing to do with which files they are defined in, only where in your app they are actually used. It looks like you are using ContentTable as a child widget of TableDisplay so you can pass information to it without problem. Just define a parameter in content_table.dart and supply a value for that parameter when you call ContentTable in your tables_display.dart, for instance:

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
  ],
),
//...

If you want to pass data between widgets used in totally different parts of your app then use Provider

Upvotes: 0

Related Questions