I have been trying to pass a entire List to a new page but a receiver this error " Exception has occurred. RangeError (RangeError (index): Invalid value: Valid value range is empty: 0) ". I believe the problem is on the page that is sending the list, since the error is apparently because the list is empty, right?
This is the code of my page that a sending the List:
import 'package:flutter/material.dart';
import 'package:flutter_cont`enter code here`ador/main.dart';
import 'package:flutter_contador/view/LeitorEAN_View.dart';
import 'package:sqflite/sqflite.dart';
import 'package:flutter_contador/data/produto.dart';
class ListaDeProdutos extends StatefulWidget {
final Future<Database>? database;
const ListaDeProdutos({Key? key, this.database}) : super(key: key);
@override
State<StatefulWidget> createState() {
return _ListaDeProdutosState();
}
}
class _ListaDeProdutosState extends State<ListaDeProdutos> {
List<Produto> listaproduto = List.empty(growable: true);
@override
void initState() {
fetchProdutos();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text('Produto'),
bottom: AppBar(
automaticallyImplyLeading: false,
elevation: 0,
title: Container(
width: double.infinity,
height: 40,
color: Colors.white,
child: const Center(
child: TextField(
// controller: _controller,
decoration: InputDecoration(
prefixIcon: Icon(Icons.search),
// hintText: (Get.put(LeitorCodigoBarrasControle()).valorCodigoBarras),
hintText: ('Buscar...'),
),
),
),
),
),
),
body: ListView.builder(
itemCount: listaproduto.length,
itemBuilder: (context, index,) {
return Card(
child: ListTile(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => LeitorCodigoBarras(database: database, listaproduto: [],)),
);
}, // alterar quantidade do produto com leitor EAN
onLongPress: (){openUpdateProdutoView(index);}, // alterar quantidade do produto manualmente
// onLongPress: (){ deleteRecord(listaproduto[index]);}, // deletar o produto
leading: Text(listaproduto[index].codigo,style: const TextStyle(fontSize: 25)),
subtitle: Column(
children: [
Text(listaproduto[index].descricao,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(fontSize: 16)
),
Text(listaproduto[index].codigoEAN,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: const TextStyle(fontSize: 16)),
],
),
trailing: Text(listaproduto[index].quantidade.toString(),style: const TextStyle(fontSize: 20)),
));
}),
);
}
void fetchProdutos() async {
final db = await widget.database;
final List<Map<String, dynamic>> maps =
await db!.query(Produto.tableName);
var list = List.generate(maps.length, (i) {
return Produto(
id: maps[i]['id'],
codigo: maps[i]['codigo'],
descricao: maps[i]['descricao'],
codigoEAN: maps[i]['codigoEAN'],
quantidade: maps[i]['quantidade'],
);
});
setState(() {
listaproduto.clear();
listaproduto.addAll(list);
});
}
// void deleteRecord(Produto produto) async {
// final db = await widget.database;
// db!.delete(Produto.tableName,
// where: 'id = ?', whereArgs: [produto.id]);
//
// fetchProdutos();
// }
void openUpdateProdutoView(int index) async {
bool doUpdate = await Navigator.pushNamed(context, "/updateProduto",
arguments: listaproduto[index]) as bool;
if (doUpdate) {
fetchProdutos();
}
}
}
This is the code of my page that a receiving the List:
import 'package:flutter/material.dart';
import 'package:flutter_contador/data/Produto.dart';
import 'package:scan/scan.dart';
import 'package:sqflite/sqflite.dart';
class LeitorCodigoBarras extends StatefulWidget {
const LeitorCodigoBarras(
{Key? key, required this.database, required this.listaproduto})
: super(key: key);
final Future<Database>? database;
final List<Produto> listaproduto;
@override
_LeitorCodigoBarrasState createState() => _LeitorCodigoBarrasState();
}
class _LeitorCodigoBarrasState extends State<LeitorCodigoBarras> {
List<Produto> listaproduto = List.empty(growable: true);
ScanController controller = ScanController();
var quantidadeEditController = TextEditingController();
var index = 0;
var quantidade = 0;
var scanResult = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
toolbarHeight: 80,
title: const Text(
'Leitor EAN',
textAlign: TextAlign.center,
),
elevation: 0.0,
backgroundColor: const Color(0xFF333333),
leading: GestureDetector(
onTap: () => Navigator.of(context).pop(),
child: const Center(
child: Icon(
Icons.cancel,
color: Colors.white,
)),
),
actions: [
IconButton(
icon: const Icon(Icons.save),
onPressed: () {
}),
IconButton(
icon: const Icon(Icons.flashlight_on),
onPressed: () {
controller.toggleTorchMode();
})
],
),
body: Column(
children: [
SizedBox(
height: 400,
child: ScanView(
controller: controller,
scanAreaScale: .7,
scanLineColor: const Color.fromARGB(255, 51, 255, 0),
onCapture: (data) {
setState(() {
scanResult = data;
for (var i = 0; i < listaproduto.length; i ) {
if (listaproduto[i].codigoEAN == scanResult) {
index = i;
}else{
ScaffoldMessenger.of(context)
..removeCurrentSnackBar()
..showSnackBar(const SnackBar(content: Text("Código EAN não encontrado.")));
}
}
});
controller.resume();
},
),
),
SingleChildScrollView(
child: ListTile(
title: Text(
'Produto ${widget.listaproduto[index].codigo}',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.black, fontSize: 40),
),
subtitle: Text(
'0000000',
textAlign: TextAlign.center,
),
),
),
const SizedBox(
child: ListTile(
title: Text(
'10',
textAlign: TextAlign.center,
),
leading: Icon(Icons.add),
trailing: Icon(Icons.remove),
),
),
],
),
);
}
}
CodePudding user response:
You pass your list as an argument to a named route, but you do not take the argument anywhere on the page where you receive the list.
Inside your build add this to receive the list:
List<Produto> list = ModalRoute.of(context)!.settings.arguments as List<Produto>;
See here: https://docs.flutter.dev/cookbook/navigation/navigate-with-arguments