Reputation: 41
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
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