Flutter Unable to update List<Map<>> datatable onSelectChanged - list

Please help - and be patient i am still learning - I have a model with constant data (until I implement my API) that provides Order data
class Orders {
static const List<String> columns = [
"ID",
"Items",
"Total",
"Status",
];
List<Map<int,String>> header = [
{0:"Order"},
{1:"Items"},
{2:"Total"},
{3:"Status"},
];
List<Map<String,dynamic>> rows = [
{"Number":390,"Items":6,"Total":450.00,"Status":"PENDING","Checked":true},
{"Number":391,"Items":19,"Total":3200.00,"Status":"PENDING","Checked":false},
{"Number":392,"Items":6,"Total":450.00,"Status":"PENDING","Checked":false},
{"Number":393,"Items":"-","Total":"-","Status":"-","Checked":false},
];
void setOrderHeader(newHeader){
header = newHeader;
}
void setOrderRows(newRows){
rows = newRows;
}
}
I then created a DataTable builder which i call on my orders_screen
import 'package:flutter/material.dart';
import 'package:one/models/orders.dart';
class DataTableBuilder extends StatefulWidget {
#override
_DataTableBuilderState createState() => _DataTableBuilderState();
}
class _DataTableBuilderState extends State<DataTableBuilder> {
List<Map<int, String>> get header => Orders().header;
List<Map<String, dynamic>> get rows => Orders().rows;
int sortColumnIndex = 0;
bool sort = true;
String rowKey = "Number";
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
int col = 0;
return SingleChildScrollView(
scrollDirection: Axis.vertical,
child: DataTable(
sortAscending: sort,
sortColumnIndex: sortColumnIndex,
showCheckboxColumn: true,
columns: header.map((e) => DataColumn(
label: _getStyledText(e[col++]!.toUpperCase(),14,Colors.black),
),
).toList(),
rows: rows.map(((rowData) => DataRow(
cells: <DataCell>[
DataCell(
_getStyledText(
rowData["Number"],
12,
Colors.black87,
),
), //Extracting from Map element the value
DataCell(
_getStyledText(
rowData["Items"],
16,
Colors.black87,
),
),
DataCell(
_getStyledText(
rowData["Total"],
12,
Colors.black87,
),
),
DataCell(
_getStyledText(
rowData["Status"],
12,
Colors.deepOrange,
),
// showEditIcon:true,
placeholder: true,
),
],
selected: rowData["Checked"],
onSelectChanged: (selected) {
if (selected==true) {
onSelectedRow(selected!, rowData,rows);
print(rows);
}
},
)),
).toList(),
),
);
}
Widget _getStyledText(dynamic rowText,double size, Color bgColor) {
return Text(
rowText.toString(),
style: TextStyle(
fontSize: size==0?14:size,
color: bgColor,
),
);
}
onSelectedRow(bool selected, Map<String,dynamic> rowData,List<Map<String,dynamic>> rows) async {
if (selected) {
for(int i = 0; i < rows.length; i++) {
if(rows[i]["Number"] == rowData["Number"]){
setState(() {
rows[i]["Checked"] = true;
Orders().setOrderRows(rows);
});
}
}
}
}
}
The issue I am having is with the onSelectChanged() and setState() methods - I would like to update the orders list to set the selected row to be checked or unchecked.
I am able to update the order data in the onSelectedRow() method but it does not seem to update my global rows variable or the setState() method is not updating the table.

Related

Not able to convert DataModel Future List to a list item

I tried to add data from populateSearch() method into the allData List in Custom search, but it doesn't accept the data.
please help me to add the data from populateSearch() into the least in the Customsearch class during the initialization so that it would be used as suggestion list during search.
I tried to search over the internet and it has been now two days without solution.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:zhebsa_assistant/model/dzongkha_zhebsa.dart';
import '../../database/za_darabase.dart';
import 'search_result.dart';
class CustomSearch extends SearchDelegate {
//bb
final DatabaseService _databaseService = DatabaseService();
late List<String> searchData;
List<SearchDataModel> items = [];
List<SearchDataModel> suggestion = [];
// ListViewNoteState i = ListViewNoteState();
Future<List<SearchDataModel>> _getSearch() async {
return await _databaseService.populateSearch();
}
// final allData = [];
List<String> allData = [
'Abc',
'Def',
'བཀའ་སློབ།',
'ཁྲག',
'སྐུ་ཁྲག',
'བཀབ་ནེ།',
];
final recentData = [
'བཀབ་ནེ།',
'བཀའ་སློབ།',
'ཁྲག',
'སྐུ་ཁྲག',
];
CustomSearch({
String hintText = "འཚོལ།/Search",
}) : super(
searchFieldLabel: hintText,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.search,
);
#override
ThemeData appBarTheme(BuildContext context) {
final ThemeData theme = Theme.of(context);
// final InputDecorationTheme? searchFieldDecorationTheme;
return theme.copyWith(
dividerTheme: const DividerThemeData(
color: Colors.white,
),
// primaryIconTheme: const IconThemeData(color: Colors.white),
scaffoldBackgroundColor: Colors.white, // for the body color
// brightness: Brightness.dark,
inputDecorationTheme: searchFieldDecorationTheme ??
const InputDecorationTheme(
// focusedBorder: UnderlineInputBorder(
// borderSide: BorderSide(color: Colors.white),
// ),
border: InputBorder.none,
hintStyle: TextStyle(
color: Colors.white,
),
),
textSelectionTheme: const TextSelectionThemeData(
cursorColor: Colors.white,
), // cursor color
textTheme: Theme.of(context).textTheme.copyWith(
headline6: const TextStyle(
color: Colors.white,
// fontSize: 20.0,
decorationThickness: 0.0000001,
),
),
);
}
#override
List<Widget>? buildActions(BuildContext context) {
return [
IconButton(
onPressed: () {
if (query.isEmpty) {
close(context, null);
} else {
query = '';
showSuggestions(context);
}
// stopPronunciation();
SearchResults(searchQuery: "").stopPronunciation();
},
icon: const Icon(Icons.clear),
)
];
}
#override
Widget? buildLeading(BuildContext context) {
return IconButton(
onPressed: () {
close(context, null);
// stopPronunciation();
SearchResults(searchQuery: "").stopPronunciation();
},
// icon: const Icon(Icons.arrow_back),
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow,
progress: transitionAnimation,
),
);
}
#override
Widget buildResults(BuildContext context) {
return SearchResults(searchQuery: query);
}
#override
Widget buildSuggestions(BuildContext context) {
final suggestionList = query.isEmpty
? recentData
: allData.where((p) {
final dataLower = p.toLowerCase();
final queryLower = query.toLowerCase();
return dataLower.startsWith(queryLower);
}).toList();
return buildSuggestionsSuccess(suggestionList);
}
Widget buildSuggestionsSuccess(List<String> suggestionList) =>
ListView.builder(
itemCount: suggestionList.length,
itemBuilder: (context, index) {
final suggestion = suggestionList[index];
final queryText = suggestion.substring(0, query.length);
final remainingText = suggestion.substring(query.length);
return ListTile(
onTap: () {
query = suggestion;
showResults(context);
},
leading: const Icon(
Icons.dangerous,
),
title: RichText(
text: TextSpan(
text: queryText,
style: const TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
),
children: [
TextSpan(
text: remainingText,
style: const TextStyle(color: Colors.black45),
),
]),
),
// title: Text(suggestionList[index]),
);
},
);
}
//SearchList Model
class SearchDataModel {
final String sWord;
SearchDataModel({required this.sWord});
Map<String, dynamic> toMap() {
return {
'sWord': sWord,
};
}
factory SearchDataModel.fromMap(Map<String, dynamic> map) {
return SearchDataModel(
sWord: map['sWord'],
);
}
String toJson() => json.encode(toMap());
factory SearchDataModel.fromJson(String source) =>
SearchDataModel.fromMap(json.decode(source));
}
import 'dart:convert';
import '../model/dzongkha.dart';
import '../model/zhebsa.dart';
import '../model/dzongkha_zhebsa.dart';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
class DatabaseService {
static final DatabaseService _databaseService = DatabaseService._internal();
factory DatabaseService() => _databaseService;
DatabaseService._internal();
static Database? _database;
Future<Database> get database async {
if (_database != null) return _database!;
_database = await _initDatabase();
return _database!;
}
Future<Database> _initDatabase() async {
final databasePath = await getDatabasesPath();
final path = join(databasePath, 'zhebsa_assistant0.db');
return await openDatabase(
path,
onCreate: _onCreate,
version: 1,
onConfigure: (db) async => await db.execute('PRAGMA foreign_keys = ON'),
);
}
Future<void> _onCreate(Database db, int version) async {
await db.execute(
'''CREATE TABLE Dzongkha(
dId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
dWord TEXT NOT NULL UNIQUE,
dPhrase TEXT,
dHistory TEXT,
dFavourite TEXT,
dUpdateTime TEXT)''',
);
await db.execute(
'''CREATE TABLE Zhebsa(
zId INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
zWord TEXT NOT NULL UNIQUE,
zPhrase TEXT,
zPronunciation TEXT,
zHistory TEXT,
zFavourite TEXT,
zUpdateTime TEXT)''',
);
// Run the CREATE {dzongkha_zhebsa} TABLE statement on the database.
await db.execute(
'CREATE TABLE DzongkhaZhebsa(DzongkhadId INTEGER NOT NULL, ZhebsazId INTEGER NOT NULL, updateTime TEXT, PRIMARY KEY (DzongkhadId, ZhebsazId), FOREIGN KEY(DzongkhadId) REFERENCES Dzongkha(dId) ON DELETE SET NULL, FOREIGN KEY(ZhebsazId) REFERENCES Zhebsa(zId) ON DELETE SET NULL)',
);
//Insert raw data to database
var dt = DateTime.now();
var dtStr = dt.toIso8601String();
await db.rawInsert(
'INSERT INTO Dzongkha(dId, dWord, dPhrase, dUpdateTime) VALUES(1, "བཀབ་ནེ།", "བཀབ་ནེ་བཀབ་གོ།", "$dtStr"),(2, "ཁ།", "ཁ། inn", "$dtStr"), (3, "བརྩེ་བ།", "བརྩེ་བ། kindness", "$dtStr")');
await db.rawInsert(
'INSERT INTO Zhebsa(zId, zWord, zPhrase, zPronunciation, zUpdateTime) VALUES(1, "སྐུ་གཟན།", "སྐུ་གཟན yes", "2.mp3", "$dtStr"), (2, "ན༌བཟའ།", "ན༌བཟའ་ཨིན།", "2.mp3", "$dtStr"), (3, "ཞལ།", "ཞལ། is correct", "3.mp3", "$dtStr"), (4, "བརྩེ་བ།", "བརྩེ་བ། honoriffic", "4.mp3", "$dtStr")');
await db.rawInsert(
'INSERT INTO DzongkhaZhebsa (DzongkhadId, ZhebsazId, updateTime) VALUES(1, 1, "$dtStr"), (1, 2, "$dtStr"), (2, 3, "$dtStr"), (3, 4, "$dtStr")');
}
Future<List<SearchDataModel>> populateSearch() async {
final db = await _databaseService.database;
final searchData = await db.rawQuery(
'(SELECT dWord FROM Dzongkha) UNION (SELECT zWord FROM Zhebsa)');
// return searchData.map((e) => SearchDataModel.fromMap(e)).toList();
return List.generate(searchData.length,
(index) => SearchDataModel.fromMap(searchData[index]));
}
}
First, edit your SearchDataModel class like this:
class SearchDataModel {
final String sWord;
SearchDataModel({required this.sWord});
factory SearchDataModel.fromMap(Map<String, Object?> map) =>
SearchDataModel(sWord: map['sWord']);
Map<String, Object?> toMap() => {'sWord': sWord};
}
Then, in your populateSearch() method, try this:
Future<List<SearchDataModel>> populateSearch() async {
final db = await _databaseService.database;
final searchData = await db.rawQuery(
'(SELECT dWord FROM Dzongkha) UNION (SELECT zWord FROM Zhebsa)');
return searchData.map(SearchDataModel.fromMap).toList();
}

flutter SingleChildScrollView remove item

I have the following code where I generate a list of items(data is taken from Firebase). I would like to implement a functionality to remove items but I don't know how to access the list and how to remove items:
class _MyOfferState extends State<MyOffer> {
List<Widget> items = [];
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
...
body: SingleChildScrollView(
child: Column(
children: [
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('Offers')
builder: (BuildContext context, snapshot) {
snapshot.data.docs.forEach((element) {
element.get('items').forEach((item) {
String _name = element['name'];
String _category = item['category'];
items.add(offer(name, category, context,...));
});
}
);
}
return new Column(
children: List.unmodifiable(() sync* {
yield* items;
}()),
);
},
),
}
}
This is a dynamic class where I have GestureDetector. The item should be deleted when a user clicks on the it.
dynamic offer(name, category, context,) {
return GestureDetector(
child: Container(
child: Row(
children: [
Text(name),
Text(category),
],
),
),
),
onTap: () {
// remove item should be here
},
);
}
Removing the offer from within itself is not the best practice but you can accomplish it in a number of ways. The first I can think of is to pass a function that removes it when creating the offer like this:
items.add(offer(name, category, context,..., () {
setState(() {
FirebaseFirestore.instance
.collection('Offers')
.doc(element['id'])
.delete();
items.remoev(index);
});
}));
You'll need to create the index beforehand and increase it each time but I don't recommend doing it.
The way I would done do this is change the offer to be:
dynamic offer(name, category, context,) {
return Container(
child: Row(
children: [
Text(name),
Text(category),
],
),
);
}
And when creating the offer wrap it in the GestureDetector like this:
items.add(GestureDetector(
child: offer(name, category, context,...)),
onTap: () {
setState(() {
FirebaseFirestore.instance
.collection('Offers')
.doc(element['id'])
.delete();
items.remoev(index);
});
},
);
You'll have to do the same thing with the index but I consider it a better approach since the child has no power over the parent and can't change its state which is a good practice.
you need to pass index of item and delete by index:
int index = 0;
snapshot.data.docs.forEach((element) {
element.get('items').forEach((item) {
String _name = element['name'];
String _category = item['category'];
items.add(offer(index, name, category, context,...));
index++;
});
Widget offer(int index, string name, string category, BuildContext context,) {
return GestureDetector(
child: Container(
child: Row(
children: [
Text(name),
Text(category),
],
),
),
),
onTap: () {
// remove item should be here
items.removeAt(index);
setState((){});
},
);
}
}
);
}
return new Column(
children: List.unmodifiable(() sync* {
yield* items;
}()),
);
Your list is getting build by Stream data the one you provided to your StreamBuilder, do create new list you need to change Stream value, I suggest to keep FirebaseFirestore.instance.collection('Offers') instance in a stream and modify the stream.
class _MyOfferState extends State<MyOffer> {
List<Widget> items = [];
StreamController _controller = StreamController();
#override
void initState() {
super.initState();
_controller.addStream( FirebaseFirestore.instance
.collection('Offers').snapshots());
}
// dont forgot to close stream
#override
void dispose() {
_controller.close();
super.dispose();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
...
body: SingleChildScrollView(
child: Column(
children: [
StreamBuilder<QuerySnapshot>(
stream: _controller.stream,
builder: (BuildContext context, snapshot) {
snapshot.data.docs.forEach((element) {
element.get('items').forEach((item) {
String _name = element['name'];
String _category = item['category'];
items.add(offer(name, category, context,(){
// remove function is here
snapshot.data.docs.removeWhere((e) => e.id == element.id);
_controller.add(snapshot.data);
});
});
}
);
}
return new Column(
children: List.unmodifiable(() sync* {
yield* items;
}()),
);
},
),
}
}
Also pass onTap to your widget function
dynamic offer(name, category, context, onTap) {
return GestureDetector(
child: Container(
child: Row(
children: [
Text(name),
Text(category),
],
),
),
),
onTap: onTap,
);
}

flutter: doesn't embed data from function to list

I want to create a list, those people location = "Barishal". That's why, I created a function and try to push data ( which data I obtained from getSpecific() function ) to a new list ( myList ). But It created a problem ....
here is my code-
class BookData extends ChangeNotifier {
List<MyModel> data = [
MyModel(name: "Abir", location: "Dhaka"),
MyModel(name: "Shuvro", location: "Barishal"),
MyModel(name: "Anik", location: "Barishal")
];
List<MyModel> get getMydata{
return data;
}
getSpecific (){
for(int i=0;i<data.length;i++){
if(data[i].location=="Barishal"){
print(data[i]);
return data[i];
}
}
}
List myList = getSpecific();
}
How can I fix this problem ?
You can copy paste run full code below
You can provide search string and use UnmodifiableListView<MyModel> and filter with _myData.where
code snippet
class BookData extends ChangeNotifier {
final List<MyModel> _myData = [
MyModel(name: "Abir", location: "Dhaka"),
MyModel(name: "Shuvro", location: "Barishal"),
MyModel(name: "Anik", location: "Barishal")
];
String _searchString = "";
UnmodifiableListView<MyModel> get books => _searchString.isEmpty
? UnmodifiableListView(_myData)
: UnmodifiableListView(
_myData.where((dog) => dog.location.contains(_searchString)));
void getSpecific(String searchString) {
_searchString = searchString;
print(_searchString);
notifyListeners();
}
}
working demo
full code
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'dart:collection';
import 'package:provider/provider.dart';
class BookData extends ChangeNotifier {
final List<MyModel> _myData = [
MyModel(name: "Abir", location: "Dhaka"),
MyModel(name: "Shuvro", location: "Barishal"),
MyModel(name: "Anik", location: "Barishal")
];
String _searchString = "";
UnmodifiableListView<MyModel> get books => _searchString.isEmpty
? UnmodifiableListView(_myData)
: UnmodifiableListView(
_myData.where((dog) => dog.location.contains(_searchString)));
void getSpecific(String searchString) {
_searchString = searchString;
print(_searchString);
notifyListeners();
}
}
class MyModel {
final String name;
final String location;
MyModel({this.name, this.location});
}
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => BookData(),
child: MyApp(),
),
);
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _controller = TextEditingController();
String _searchText;
#override
void initState() {
_controller.addListener(
() {
setState(() {
_searchText = _controller.text;
});
},
);
super.initState();
}
#override
void dispose() {
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Example',
home: Scaffold(
appBar: AppBar(
title: Text('Example'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
TextField(
controller: _controller,
decoration: InputDecoration(
hintText: "Search",
prefixIcon: Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(4.0),
),
),
),
onChanged: (value) {
Provider.of<BookData>(context, listen: false)
.getSpecific(value);
},
),
Consumer<BookData>(builder: (context, bookData, child) {
print(bookData.books.toString());
return Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: bookData.books.length,
itemBuilder: (context, index) => Card(
elevation: 3,
child: ListTile(
title: Text(bookData.books[index].name),
),
)),
);
}),
],
),
),
);
}
}
When you need to filter a list, you can use the where method.
Here's a simple example.
List<MyModel> myNewList = data.where((item) => item.location == "Barishal").toList();
Anyway, your code seems to be returning just the first item, not a list.
I fixed your code like below
List<MyModel> getSpecific (){
List<MyModel> result = [];
for(int i=0;i<data.length;i++){
if(data[i].location=="Barishal"){
print(data[i]);
result.add(data[i]);
}
}
return result;
}

Flutter: `notifyListeners` not updating the list

I am trying to list categories of products in my app, and i am using provider package for state management. During the build time its shows the list is empty even though it is not, then I add a click event to update the list that time it works.
I call the getAllCategories() function during the splash screen and the vallCategoryList has values.
This is my category class
class Category with ChangeNotifier{
int catId;
String catName;
String catThumbnail;
List<SetCategory> allCategoryList = [];
void getAllCategories() async {
String categoryUrl = 'https://app.ecwid.com/api/ccccccc';
Response allCategory = await get(categoryUrl);
print('getAllCategories');
if (allCategory.statusCode == 200) {
var categoryData = allCategory.body;
int totalcount = jsonDecode(categoryData)['count'];
if (allCategoryList.length != totalcount) {
allCategoryList.clear();
for (int i = 0; i < totalcount; i++) {
allCategoryList.add(SetCategory(
catId: jsonDecode(categoryData)['items'][i]['id'],
catName: jsonDecode(categoryData)['items'][i]['name'],
catThumbnail: jsonDecode(categoryData)['items'][i]['thumbnailUrl'],
));
}
}
}
print('allcategorylist length ${allCategoryList.length}');
notifyListeners();
}
}
class SetCategory {
int catId;
String catName;
String catThumbnail;
SetCategory(
{ this.catId, this.catName, this.catThumbnail});
}
My code for screen
class HomeScreen extends StatefulWidget {
static const String id = 'homeScreen';
// static int reload = 0;
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
#override
Widget build(BuildContext context) {
final category = Provider.of<Category>(context);
print('category length ${category.allCategoryList.length}'); // here it shows length as 0 even though it has a value of 16.
return Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Category ${category.allCategoryList.length}',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 15.0,
),
textAlign: TextAlign.start,
),
),
InkWell(
onTap: () {
category.getAllCategories(); // when i tap here this updates the list
}),
],
),
Did you use ChangeNotifierProvider in your Widget as shown here
If you just used Provider it is not updating but just makes the object accessible from the descendants
Solved by adding a Consumer, changed code like this
child: Consumer<Category>(
builder: (_,category,__){
return ListView.builder();
}

error: The named parameter 'children' isn't defined, while using a ListView

I am using Firebase realtime database to retrieve information and then present it in a scrollable DataTable.
To make the DataTable scrollable, I wrapped it up in a ListView, as per the comment of this post:
DataTable - make scrollable, set background colour and fix/freeze header row and first column
This is my code:
import 'package:flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';
import 'cprdata.dart';
import 'dart:convert';
class CprAnalysis extends StatefulWidget {
#override
CPRState createState() => CPRState();
}
class CPRState extends State<CprAnalysis> {
///var cpr = UpdateData.getData();
List<FilterData> acData;
List<FilterData> getData() {
var cpr = <FilterData>[];
DatabaseReference cprData = FirebaseDatabase.instance.reference();
cprData.reference().once().then((DataSnapshot snap) {
var d = snap.value;
final jsonE = json.encode(d);
final jsonResponse = json.decode(jsonE);
MyDataList zz = new MyDataList.fromJson(jsonResponse);
zz.myList.forEach((data) {
cpr.add(FilterData(sYMBOL: data.SYMBOL, fORECAST: data.FORECAST));
}
);
},
);
print(cpr);
return cpr;
}
#override
void initState() {
super.initState();
acData = getData();
}
Widget bodydata() => Expanded(
child: ListView(
///shrinkWrap: true,
padding: const EdgeInsets.all(8.0),
childern: <Widget>[
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
columns: <DataColumn>[
DataColumn(
label: Text("Symbol"),
numeric: false,
),
DataColumn(
label: Text("Forecast"),
numeric: false,
),
],
rows: acData.map((data) =>
DataRow(
cells: [
DataCell(
Text(data.sYMBOL),
showEditIcon: false,
placeholder: false,
),
DataCell(
Text(data.fORECAST),
showEditIcon: false,
placeholder: false,
)
],
),
)
.toList()
),
),
]
),
);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("CPR Analysis"),
),
body: Container(
child: bodydata(),
),
);
}
}
class FilterData {
String sYMBOL, fORECAST;
FilterData({
this.sYMBOL,
this.fORECAST});
}
Expected output: Scrollable DataTable.
Actual output: error: The named parameter 'childern' isn't defined under ListView()
You misspelled children as childern in your code.
Make your ListView code as -
ListView(
children: <Widget> [
//Your remaining code
]
),