I am getting the following error in my code.
The getter 'todoText' isn't defined for the class 'String'.
Try importing the library that defines 'todoText', correcting the name to the name of an existing getter, or defining a getter or field named 'todoText'.dart(undefined_getter)
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
void main() => runApp(new ToDoApp());
class ToDoApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'To Do Application',
theme: new ThemeData(
primarySwatch: Colors.teal,
),
home: new ToDoList(),
);
}
}
class ListItem{
bool _todoCheck;
ListItem(this._todoCheck);
}
class _strikeThrough extends StatelessWidget{
final String todoText;
final bool todoCheck;
_strikeThrough(this.todoText, this.todoCheck) : super();
Widget _widget(){
if(todoCheck){
return Text(
todoText,
style: TextStyle(
decoration: TextDecoration.lineThrough,
fontStyle: FontStyle.italic,
fontSize: 22.0,
color: Colors.red[200],
),
);
}
else{
return Text(
todoText,
style: TextStyle(
fontSize: 22.0
),
);
}
}
#override
Widget build(BuildContext context){
return _widget();
}
}
class ToDoList extends StatefulWidget {
#override
createState() => new _TodoListState();
}
class _TodoListState extends State<ToDoList> {
var textController = TextEditingController();
var popUpTextController = TextEditingController();
List<String> _todoItems = [];
List<ListItem> WidgetList =[];
void _addToDoItem(String task){
if(task.length > 0){
setState(()=> _todoItems.add(task));
}
}
void _removeToDoItem(int index){
setState(() => _todoItems.removeAt(index));
}
void _promptRemoveToDoItem(int index){
showDialog(context: context,
builder: (BuildContext context){
return new AlertDialog(
title: new Text('Mark "${_todoItems[index]}" as Completed?'+' This will remove this Item'),
actions: <Widget>[
new FlatButton(
child: new Text('CANCEL'),
onPressed: () => Navigator.of(context).pop()
),
new FlatButton(
child: new Text('MARK AS DONE'),
onPressed: () {
_removeToDoItem(index);
Navigator.of(context).pop();
Fluttertoast.showToast(
msg: 'ToDo Task Deleted!'
);
}
),
]
);
}
);
}
Widget _buildToDoList(BuildContext context){
return Column(
children: <Widget>[
new Flexible(
child: new ListView.builder(
itemBuilder: (context,index){
return _buildToDoItem(_todoItems[index], index);
},
),
),
new Expanded(
child: ReorderableListView(
children: <Widget>[
for(final widget in _todoItems)
for(final widget1 in WidgetList)
GestureDetector(
key: Key(widget.todoText),
child: Dismissible(
key: Key(widget.todoText),
child: CheckboxListTile(
value: widget1._todoCheck,
title: _strikeThrough(widget.todoText,widget1._todoCheck),
onChanged: (checkValue){
setState(() {
if(!checkValue){
widget1._todoCheck = false;
}
else{
widget1._todoCheck = true;
}
});
}),
background: Container(
child: Icon(Icons.delete),
alignment: Alignment.centerRight,
color: Colors.orange[300],
),
confirmDismiss: (dismissDirection){
return showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context){
return AlertDialog(
title: Text("Delete Todo?"),
actions: <Widget>[
FlatButton(
child: Text("OK"),
onPressed: (){
Navigator.of(context).pop(true);
},
),
FlatButton(
child: Text("Cancel"),
onPressed: (){
Navigator.of(context).pop(true);
},),
],
);
});
},
direction: DismissDirection.endToStart,
movementDuration: const Duration(milliseconds: 200),
onDismissed: (dismissedDirection){
WidgetList.remove(widget);
Fluttertoast.showToast(
msg: "Todo Deleted!"
);
},
),
onDoubleTap: (){
popUpTextController.text = widget.todoText;
showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context){
return AlertDialog(
title: Text("Edit ToDo"),
content: TextFormField(
controller: popUpTextController,
),
actions: <Widget>[
FlatButton(
child: Text("OK"),
onPressed: (){
setState(() {
widget.todoText=popUpTextController.text;
});
Navigator.of(context).pop(true);
},
),
FlatButton(
child: Text("Cancel"),
onPressed: (){
Navigator.of(context).pop(false);
},
)
],
);
}
);
},
)
],
onReorder: (oldIndex, newIndex){
setState(() {
if(oldIndex < newIndex){
newIndex -= 1;
}
var replaceWiget = WidgetList.removeAt(oldIndex);
WidgetList.insert(newIndex, replaceWiget);
});
},)
)
],
);
}
Widget _buildToDoItem(String todoText, int index){
return new ListTile(
title: new Text(todoText),
onLongPress: () => _promptRemoveToDoItem(index),
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('To Do List')
),
body:_buildToDoList(context),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: new FloatingActionButton(
focusElevation: 7,
onPressed:_pushAddToDoScreen,
tooltip: 'Add Task',
child: new Icon(Icons.add)
),
drawer: Drawer(
child: ListView(
padding: const EdgeInsets.all(0),
children: <Widget>[
DrawerHeader(
child: Text('To Do App Drawer Header'),
decoration: BoxDecoration(
color: Colors.teal,
)
),
ListTile(
title: Text('Add Items'),
onTap: _pushAddToDoScreen,
),
ListTile(
title: Text('Remove Items'),
subtitle: Text('Long Press on any item to remove it'),
onTap: (){
Navigator.pop(context);
},
),
ListTile(
title: Text('Check Status of Items'),
subtitle: Text('If the item is in List, then it is Pending, else long press to mark it done'),
onTap: (){
Navigator.pop(context);
},
),
],
)
),
bottomNavigationBar: BottomAppBar(
shape: CircularNotchedRectangle(),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(Icons.settings),
onPressed: () {},
),
IconButton(
icon: Icon(Icons.more_vert),
onPressed: () {},
)
]
)
)
);
}
void _pushAddToDoScreen(){
Navigator.of(context).push(
new MaterialPageRoute(
builder: (context){
return new Scaffold(
appBar: new AppBar(
title: new Text('Add a new task')
),
body: new TextField(
autofocus: true,
onSubmitted: (val){
_addToDoItem(val);
Navigator.pop(context);
},
decoration: new InputDecoration(
hintText: 'Enter Tasks....',
contentPadding: const EdgeInsets.all(16.0)
),
)
);
}
)
);
}
}
Related
I have a NavigationBar with 3 tabs and i want to change the current tab or destination when i push on a button.
The Navigation Bar on the class Home:
body:IndexedStack(
index: currentPageIndex,
children: <Widget>[
const ShopPage(),
QRScanner(showTab2: () {
setState(() {
setState(() {
currentPageIndex = 2;
});
});
}),
const ShopListPage(),
],
),
bottomNavigationBar: NavigationBar(
elevation: 2,
labelBehavior: NavigationDestinationLabelBehavior.onlyShowSelected,
selectedIndex: currentPageIndex,
onDestinationSelected: (int index) {
setState(() => currentPageIndex = index);
},
destinations: const [
NavigationDestination(
icon: Icon(Icons.store_outlined),
selectedIcon: Icon(Icons.store),
label: 'Tienda',
),
NavigationDestination(
icon: Icon(Icons.qr_code_scanner_outlined),
selectedIcon: Icon(Icons.qr_code_scanner),
label: 'Escaner',
),
NavigationDestination(
icon: Icon(Icons.shopping_cart_outlined),
selectedIcon: Icon(Icons.shopping_cart),
label: 'Carrito',
),
],
),
The function with the show dialog on the QRScanner page
void onQRViewCreated(QRViewController controller) {
setState(() {
this.controller = controller;
});
controller.scannedDataStream.listen((scanData) {
setState(() {
result = scanData;
});
controller.pauseCamera();
Stream<List<Products>> readProducts() => FirebaseFirestore.instance
.collection('products')
.where('id', isEqualTo: '${result!.code}')
.snapshots()
.map((snapshot) => snapshot.docs
.map((doc) => Products.fromJson(doc.data()))
.toList());
Future<bool> onWillPop() async {
return false;
}
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) => WillPopScope(
onWillPop: () async => false,
child: WillPopScope(
onWillPop: onWillPop,
child: Dialog(
insetPadding: const EdgeInsets.all(8),
child: StreamBuilder<List<Products>>(
stream: readProducts(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text('Algo ha ocurrido! ${snapshot.error}');
} else if (snapshot.hasData) {
final products = snapshot.data!;
return Container(
margin: const EdgeInsets.all(8),
child: Column(
mainAxisSize: MainAxisSize.min,
children: products
.map((p) => BuildQRCards( // This is the class which contain the button that should change tab on pressed
products: p, controller: controller,))
.toList()),
);
} else {
return const Center(child: CircularProgressIndicator());
}
}),
),
),
),
);
});
}
The BuildQRCard Class:
class _BuildQRCardsState extends State<BuildQRCards> {
#override
Widget build(BuildContext context) {
return Card(
clipBehavior: Clip.antiAlias,
child: SizedBox(
width: 300,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Image(image: NetworkImage(widget.products.imageUrl)),
ListTile(
title: Text(widget.products.name),
subtitle: Text('Precio: ${widget.products.price}\$'),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 8, 8),
child: ElevatedButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(
const Color(0xFFFFFFFF),
),
backgroundColor: MaterialStateProperty.all<Color>(
const Color(0xFF6750A4),
),
),
onPressed: () {
Navigator.pop(context);
widget.controller!.resumeCamera();
},
child: const Text(
'Cancelar',
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 8, 8),
child: ElevatedButton(
style: ButtonStyle(
foregroundColor: MaterialStateProperty.all<Color>(
const Color(0xFFFFFFFF),
),
backgroundColor: MaterialStateProperty.all<Color>(
const Color(0xFF6750A4),
),
),
onPressed: () => showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) => AlertDialog(
content: Text(
'¿Desea añadir el producto ${widget.products.name} a la lista de compras?',
textAlign: TextAlign.center,
),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('Cancelar')),
TextButton(
onPressed: () {
passID(widget.products.id);
widget.controller!.resumeCamera();
},
child: const Text('Añadir'),
),
],
),
),
child: const Text(
'Añadir al Carro',
),
),
),
],
),
],
),
),
);
}
}
new answer
This has two approaches
Using a function and using result from navigator.pop
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return const MaterialApp(home: NavigationExample());
}
}
class NavigationExample extends StatefulWidget {
const NavigationExample({super.key});
#override
State<NavigationExample> createState() => _NavigationExampleState();
}
class _NavigationExampleState extends State<NavigationExample> {
int currentPageIndex = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: NavigationBar(
onDestinationSelected: (int index) {
setState(() {
currentPageIndex = index;
});
},
selectedIndex: currentPageIndex,
destinations: const <Widget>[
NavigationDestination(
icon: Icon(Icons.explore),
label: 'Explore',
),
NavigationDestination(
icon: Icon(Icons.commute),
label: 'Commute',
),
NavigationDestination(
selectedIcon: Icon(Icons.bookmark),
icon: Icon(Icons.bookmark_border),
label: 'Saved',
),
],
),
body: <Widget>[
MyPage1(
showTab2: () {
// how to use a function when they are in the same tab list
setState(() {
setState(() {
currentPageIndex = 2;
});
});
},
),
Container(
color: Colors.green,
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Page 2'),
TextButton(
onPressed: () async {
// how to use the result
final int? result =
await Navigator.push(context, MaterialPageRoute(
builder: (context) {
return MyNewPage();
},
));
if (result != null) {
setState(() {
currentPageIndex = result;
});
}
},
child: Text("new page"))
],
),
),
Container(
color: Colors.blue,
alignment: Alignment.center,
child: const Text('Page 3'),
),
][currentPageIndex],
);
}
}
class MyPage1 extends StatelessWidget {
final Function showTab2;
const MyPage1({Key? key, required this.showTab2}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
color: Colors.red,
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Page 1'),
TextButton(
onPressed: () {
showTab2();
},
child: Text("Show tab 3"))
],
),
);
}
}
class MyNewPage extends StatelessWidget {
const MyNewPage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Center(
child: TextButton(
onPressed: () => showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) => AlertDialog(
content: Text(
'¿Desea añadir el producto ${'widget.products.name'} a la lista de compras?',
textAlign: TextAlign.center,
),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.pop(context);
Navigator.pop(context);
},
child: const Text('Cancelar')),
TextButton(
onPressed: () {
// passID(widget.products.id);
// widget.controller!.resumeCamera();
Navigator.pop(context);
Navigator.pop(context, 0);
},
child: const Text('Añadir'),
),
],
),
),
child: Text("Show dialog"),
),
)),
);
}
}
/// END OF NEW ANSWER
//old answer
This line is what changes the tabs
setState(() {
setState(() => this.index = index);
});
Hence if you want to change the tab through a different button just add something like this
setState(() {
setState(() => this.index = newTabIndex);
});
where newTabIndex is the index of the tap you want to
in your case, you might have something like this
TextButton(
onPressed: () {
passID(products.id);
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) =>
BuildListCards(
products: products)));
controller!.resumeCamera();
setState(() {
setState(() => this.index = 1); // I am assuming 1 is the index of the tab you want to show
});
},
child: const Text('Añadir')),
I'm working on a list in flutter that can be reordered.
However, I am getting an error.
I thought showDialog and builder were the cause of the error, so I turned off showDialog and tried again, but the error still occurred.
How to solve this problem or
How do I create a List using ReorderableListView.builder and showDialog?
I do not understand English, so some words and sentences may be wrong.
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
void main() {
// 最初に表示するWidget
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
// 右上に表示される"debug"ラベルを消す
debugShowCheckedModeBanner: false,
// アプリ名
title: 'My Todo App',
theme: ThemeData(
// テーマカラー
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
// リスト一覧画面を表示
home: TodoListPage(),
);
}
}
// リスト一覧画面用Widget
class TodoListPage extends StatefulWidget {
#override
_TodoListPageState createState() => _TodoListPageState();
}
class _TodoListPageState extends State<TodoListPage> {
// Todoリストのデータ
List<String> todoList = [];
void reorderData(int oldindex, int newindex) {
setState(() {
if (newindex > oldindex) {
newindex -= 1;
}
final items = todoList.removeAt(oldindex);
todoList.insert(newindex, items);
});
}
void sorting() {
setState(() {
todoList.sort();
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
// AppBarを表示し、タイトルも設定
appBar: AppBar(
title: Text('List list'),
),
// データを元にListViewを作成
body: ReorderableListView.builder(
itemCount: todoList.length,
itemBuilder: (context, index) {
return Column(
children: <Widget>[
for (final items in todoList)
GestureDetector(
onTap: () async {
// ダイアログを表示------------------------------------
showDialog(
context: context,
builder: (BuildContext context) {
return Column(
children: <Widget>[
AlertDialog(
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Column(
children: <Widget>[
TextButton.icon(
icon: const Icon(
Icons.add,
color: Colors.black,
),
label: const Text('Edit'),
onPressed: () {
sorting();
},
onLongPress: () async {
var morenewText =
await Navigator.of(context)
.push(
MaterialPageRoute(
builder: (context) =>
TodoAddPage(
todoList[index]),
),
);
setState(() {
todoList[index] = morenewText;
});
},
),
ElevatedButton(
child: const Text('Delete'),
onPressed: () {
setState(() {});
todoList.removeAt(index);
Navigator.pop(context);
},
style: ElevatedButton.styleFrom(
primary: Colors.blue,
),
),
ElevatedButton(
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
),
],
),
),
),
],
);
},
);
},
key: ValueKey(items),
child: ListTile(
title: Text(todoList[index]),
),
),
],
);
},
onReorder: reorderData,
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
// "push"で新規画面に遷移
// リスト追加画面から渡される値を受け取る
var newListText = await Navigator.of(context).push(
MaterialPageRoute(builder: (context) {
// 遷移先の画面としてリスト追加画面を指定
return TodoAddPage(null);
}),
);
if (newListText != null) {
// キャンセルした場合は newListText が null となるので注意
setState(() {
// リスト追加
todoList.add(newListText);
});
}
},
child: Icon(Icons.add),
),
);
}
}
class TodoAddPage extends StatefulWidget {
final oldnama;
TodoAddPage(this.oldnama);
#override
_TodoAddPageState createState() => _TodoAddPageState();
}
class _TodoAddPageState extends State<TodoAddPage> {
var newname = '';
#override
Widget build(BuildContext context) {
if (widget.oldnama != null) {
newname = widget.oldnama;
}
return Scaffold(
appBar: AppBar(
title: Text('Add list'),
),
body: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// 入力されたテキストを表示
const SizedBox(height: 8),
// テキスト入力
TextFormField(
//テキスト入力の初期値を決める
initialValue: newname,
// 入力されたテキストの値を受け取る(valueが入力されたテキスト)
onChanged: (String value) {
// データが変更したことを知らせる(画面を更新する)
// データを変更
newname = value;
},
),
const SizedBox(height: 8),
Container(
// 横幅いっぱいに広げる
width: double.infinity,
// リスト追加ボタン
child: ElevatedButton(
onPressed: () {
// "pop"で前の画面に戻る
// "pop"の引数から前の画面にデータを渡す
Navigator.of(context).pop(newname);
},
child: Text('Add list', style: TextStyle(color: Colors.white)),
),
),
const SizedBox(height: 8),
Container(
// 横幅いっぱいに広げる
width: double.infinity,
// キャンセルボタン
child: TextButton(
// ボタンをクリックした時の処理
onPressed: () {
// "pop"で前の画面に戻る
Navigator.of(context).pop();
},
child: Text('Cancel'),
),
),
],
),
),
);
}
}
You're using itemBuilder: wrong. Update it using this...
itemBuilder: (context, index) {
return ListTile(
key: ValueKey(todoList[index]),
onTap: () {
// ダイアログを表示------------------------------------
showDialog(
context: context,
builder: (BuildContext context) {
return Column(
children: <Widget>[
AlertDialog(
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Column(
children: <Widget>[
TextButton.icon(
icon: const Icon(
Icons.add,
color: Colors.black,
),
label: const Text('Edit'),
onPressed: () {
sorting();
},
onLongPress: () async {
var morenewText =
await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
TodoAddPage(todoList[index]),
),
);
setState(() {
todoList[index] = morenewText;
});
},
),
ElevatedButton(
child: const Text('Delete'),
onPressed: () {
setState(() {});
todoList.removeAt(index);
Navigator.pop(context);
},
style: ElevatedButton.styleFrom(
primary: Colors.blue,
),
),
ElevatedButton(
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
),
],
),
),
),
],
);
},
);
},
title: Text(todoList[index]),
);
},
I created a task list where you can add tasks and then long press them to delete the item
there maybe some confusion since i deleted some irrelevant pages from the app to the question asked
so if any error pops up i can help you with it
i wanna save the list that i created either locally on my phone or through a database(Mango db)
and thanks for the help
import 'dart:async';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/material.dart';
void main() => runApp(new TodoApp());
class TodoApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Todo List',
home: new TodoList(),
debugShowCheckedModeBanner: false,
);
}
}
class TodoList extends StatefulWidget {
#override
createState() => new TodoListState();
}
class TodoListState extends State<TodoList> {
List<String> _todoItems = [];
int _counter;
Future<File> _incrementCounter() {
setState(() {
_counter++;
});
}
void _addTodoItem(String task) {
if(task.length > 0) {
setState(() => _todoItems.add(task));
}
}
void _removeTodoItem(int index) {
setState(() => _todoItems.removeAt(index));
}
void _promptRemoveTodoItem(int index) {
showDialog(
context: context,
builder: (BuildContext context) {
return new AlertDialog(
title: new Text('Mark "${_todoItems[index]}" as done?'),
actions: <Widget>[
new FlatButton(
child: new Text('CANCEL'),
onPressed: () => Navigator.of(context).pop()
),
new FlatButton(
child: new Text('MARK AS DONE'),
onPressed: () {
_removeTodoItem(index);
Navigator.of(context).pop();
}
)
]
);
}
);
}
Widget _buildTodoList() {
return new ListView.builder(
itemBuilder: (context, index) {
if(index < _todoItems.length) {
return _buildTodoItem(_todoItems[index], index);
}
},
);
}
Widget _buildTodoItem(String todoText, int index) {
return new ListTile(
title: new Text(todoText),
onLongPress: () => _promptRemoveTodoItem(index)
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Test List')
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
Container(
height: 88,
child: DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text(
'options',
style: TextStyle(
color: Colors.black,
fontSize: 28,
),
textAlign: TextAlign.center,
),
),
),
ListTile(
leading: Icon(Icons.message),
title: Text('inbox'),
subtitle: Text('A sub test'),
),
ListTile(
leading: Icon(Icons.account_circle),
title: Text('tasks'),
subtitle: Text('A sub test'),
),
ListTile(
leading: Icon(Icons.settings),
title: Text('Settings'),
subtitle: Text('A sub test'),
),
],
),
),
body: _buildTodoList(),
floatingActionButton: new FloatingActionButton(
onPressed: _pushAddTodoScreen,
tooltip: 'Add task',
child: new Icon(Icons.add)
),
);
}
void _pushAddTodoScreen() {
Navigator.of(context).push(
new MaterialPageRoute(
builder: (context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Add a new task')
),
body: TextField(
autofocus: true,
onSubmitted: (val) {
_addTodoItem(val);
Navigator.pop(context); // Close the add todo screen
},
decoration: new InputDecoration(
hintText: 'Enter something to do...',
contentPadding: const EdgeInsets.all(16.0)
),
)
);
}
)
);
}
}
class ThirdPage extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return new ThirdPageState();
}
}
class ThirdPageState extends State<ThirdPage> {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("New Task"),
actions: <Widget>[
new IconButton(icon: const Icon(Icons.save), onPressed: () {
})
],
),
body: new Column(
children: <Widget>[
new ListTile(
leading: const Icon(Icons.person),
title: new TextField(
decoration: new InputDecoration(
hintText: "Task Name",
contentPadding: const EdgeInsets.all(15.0),
),
),
),
new ListTile(
leading: const Icon(Icons.person),
title: new TextField(
decoration: new InputDecoration(
hintText: "Responsable",
contentPadding: const EdgeInsets.all(15.0)),
keyboardType: TextInputType.phone,
maxLength: 10,
),
),
new ListTile(
leading: const Icon(Icons.email),
title: new TextField(
decoration: new InputDecoration(
hintText: "GroupName",
contentPadding: const EdgeInsets.all(15.0),
),
),
),
new ListTile(
leading: const Icon(Icons.email),
title: new TextField(
decoration: new InputDecoration(
hintText: "Project",
contentPadding: const EdgeInsets.all(15.0),
),
),
),
],
),
);
}
}
I am getting RangeError when I delete the data from the firebase realtime database using flutter application.
Here is the error
I/flutter (10577): The following RangeError was thrown building:
I/flutter (10577): RangeError (index): Invalid value: Valid value range is empty: 0
And the error is appearing after this function executes
_deleteTask(int index)
Following is the code
import 'package:firebase_database/ui/firebase_animated_list.dart';
import 'package:flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';
import '../Task.dart';
import 'package:intl/intl.dart';
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final FirebaseDatabase database = new FirebaseDatabase();
DatabaseReference databaseReference;
List<Task> tasks = List();
Task task;
#override
void initState() {
super.initState();
databaseReference = database.reference().child("Notes");
task = Task("", "");
databaseReference.onChildAdded.listen(_childAdded);
databaseReference.onChildChanged.listen(_childChanged);
//databaseReference.onChildRemoved.listen(_childDlt);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.black54,
title: Text(
"Todo",
style: TextStyle(color: Colors.white),
),
actions: <Widget>[
IconButton(
icon:Icon(Icons.done_all),
onPressed: (){
setState(() {
databaseReference.remove();
});
},
)
],
),
body: Container(
color: Colors.black,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
Flexible(
child: FirebaseAnimatedList(
query: databaseReference,
itemBuilder: (context, DataSnapshot snapshot,
Animation<double> animation, int indexxx) {
return Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
color: Colors.white30,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ListTile(
onTap: ()=>_editTask(indexxx),
title: Text("${tasks[indexxx].task}",style: TextStyle(color: Colors.white,fontSize: 18,fontWeight: FontWeight.w600),),
subtitle: Text("Created on: ${tasks[indexxx].date}",style: TextStyle(color: Colors.white,fontStyle: FontStyle.italic)),
trailing: IconButton(
icon: Icon(Icons.remove_circle,color: Colors.red,),
onPressed: ()=>_deleteTask(indexxx),
)
),
),
);
}),
)
],
),
),
),
floatingActionButtonLocation:FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add,color: Colors.blue,size: 40,),
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.0)
),
onPressed: ()=>_newTask(),
//label: Text("New Task"),
),
);
}
_newTask(){
TextEditingController textEditingController=TextEditingController();
var alert=AlertDialog(
title: Text("Add New Task"),
content: TextField(
controller: textEditingController,
decoration: InputDecoration(
labelText: "Enter Text"
//hintText: "Enter Text",
),
autofocus: true,
),
actions: <Widget>[
FlatButton(
child: Text("Cancel"),
onPressed: (){
Navigator.of(context).pop();
},
),
FlatButton(
child: Text("Add"),
onPressed: (){
String text=textEditingController.text;
DateTime now = DateTime.now();
String formattedDate = DateFormat('MMM d,y').format(now);
task.date=formattedDate;
task.task=text;
databaseReference.push().set(task.toJson());
Navigator.of(context).pop();
},
),
],
);
showDialog(context: context,builder:(context){
return alert;
});
}
_editTask(int index) {
TextEditingController textEditingController=TextEditingController();
textEditingController.text=tasks.elementAt(index).task;
var alert=AlertDialog(
title: Text("Edit Task"),
content: TextField(
controller: textEditingController,
decoration: InputDecoration(
labelText: "Enter Text",
//hintText: "Enter Text",
),
autofocus: true,
),
actions: <Widget>[
FlatButton(
child: Text("Cancel"),
onPressed: (){
Navigator.of(context).pop();
},
),
FlatButton(
child: Text("Update"),
onPressed: (){
String text=textEditingController.text;
DateTime now = DateTime.now();
String formattedDate = DateFormat('MMM d,y').format(now);
task.date=formattedDate;
task.task=text;
databaseReference.child(tasks.elementAt(index).key).update(task.toJson());
setState(() {
Navigator.of(context).pop();
});
},
),
],
);
showDialog(context: context,builder:(context){
return alert;
});
}
_deleteTask(int index) {
setState(() {
databaseReference.child(tasks.elementAt(index).key).remove();
tasks.removeAt(index);
});
}
void _childAdded(Event event) {
setState(() {
tasks.add(Task.fromSnapshot(event.snapshot));
});
}
void _childChanged(Event event) {
var oldTask=tasks.singleWhere((entry){
return event.snapshot.key==entry.key;
});
setState(() {
tasks[tasks.indexOf(oldTask)]=Task.fromSnapshot(event.snapshot);
});
}
}
I made this very simple aplication but im having a problem with it.
On every action that i do (like deleting something) the keyboard opens automatically.
I want to avoid that, and open the keyboard only when i click on the text form field (line 178 on code).
How can i do that?
I know this is something very simple to make, i have tried some things using focusnode, trying to disable the autofocus, but i didnt could make it work the way i need.
import 'dart:convert';
import 'dart:ffi';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(MaterialApp(
home: Pedidos(),
));
}
class Pedidos extends StatefulWidget {
#override
_PedidosState createState() => _PedidosState();
}
class _PedidosState extends State<Pedidos> with TickerProviderStateMixin {
TabController _tabController;
final _pecasController = TextEditingController();
List _pecasList = [];
var _firstPress = true;
#override
void initState() {
super.initState();
_tabController = new TabController(length: 3, vsync: this);
}
void _addPecas() {
if ((_pecasController.text.isEmpty) ||
((_pecasController.text.trimLeft() == ("")))) {
print("Campo Vazio");
} else {
setState(() {
Map<String, dynamic> newPeca = Map();
newPeca["title"] = _pecasController.text.trimLeft();
//newPeca["ok"] = false;
_pecasController.text = "";
_pecasList.add(newPeca);
// _saveData();
print(_pecasList);
});
}
}
void _enviar() {
if (_pecasList.length < 1) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text("Lista vazia"),
actions: <Widget>[
new FlatButton(
child: new Text("Fechar"),
onPressed: () {
Navigator.of(context).pop();
}),
]);
});
} else {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text("Deseja enviar os itens?"),
actions: <Widget>[
new FlatButton(
child: new Text("Fechar"),
onPressed: () {
Navigator.of(context).pop();
}),
new FlatButton(
child: new Text("Enviar"),
onPressed: () async {
Map<String, String> headers = new Map<String, String>();
headers["Content-type"] = "application/json";
headers["Accept"] = "application/json";
//String str = '{"take":55, "skip":"0"}';
final resp = await http.post('http://172.16.14.109:5000/',
//body: str,
body: jsonEncode(_pecasList),
headers: headers);
if (resp.statusCode == 200) {
if (resp.body == "ok") {
setState(() {
print(_pecasList);
_pecasList.clear();
Navigator.of(context).pop();
});
} else {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text(
"Erro: entre em contato com o suporte."),
actions: <Widget>[
new FlatButton(
child: new Text("Fechar"),
onPressed: () {
Navigator.of(context).pop();
Navigator.of(context).pop();
}),
]);
});
}
}
})
],
);
},
);
}
}
void _apagarTudo() {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text("Deseja limpar a lista?"),
actions: <Widget>[
new FlatButton(
child: new Text("Fechar"),
onPressed: () {
Navigator.of(context).pop();
}),
new FlatButton(
child: new Text("Limpar"),
onPressed: () {
setState(() {
_pecasList.clear();
Navigator.of(context).pop();
});
}),
]);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
"Solicitação de Peças",
style: TextStyle(fontWeight: FontWeight.bold),
),
centerTitle: true,
backgroundColor: Colors.green,
),
body: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Expanded(
flex: 8,
child: TextFormField(
controller: _pecasController,
keyboardType: TextInputType.text,
style: TextStyle(
color: Colors.black,
fontSize: 18,
),
decoration: InputDecoration(
hintText: ("Adicionar item"),
),
),
),
Padding(
padding: EdgeInsets.only(right: 15),
),
Expanded(
flex: 2,
child: RaisedButton(
child: Icon(Icons.add, color: Colors.amber),
color: Colors.green,
onPressed: _addPecas,
),
)
],
),
),
Divider(
height: 02.0,
),
Expanded(
child: ListView.builder(
itemCount: _pecasList.length,
itemBuilder: (context, index) {
return ListTile(
dense: true,
key:
Key(DateTime.now().millisecondsSinceEpoch.toString()),
title: Text(
_pecasList[index]["title"],
style: TextStyle(fontSize: 15.0),
),
trailing: Icon(
Icons.delete_forever,
color: Colors.redAccent,
),
onLongPress: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title:
new Text("Deseja remover o item da lista?"),
actions: <Widget>[
new FlatButton(
child: new Text("Fechar"),
onPressed: () {
Navigator.of(context).pop();
},
),
new FlatButton(
child: new Text("Excluir"),
onPressed: () {
_pecasList.removeAt(index);
setState(() {
Navigator.of(context).pop();
});
},
),
],
);
},
);
});
}),
),
Row(
mainAxisAlignment: (MainAxisAlignment.center),
children: <Widget>[
Padding(
padding: const EdgeInsets.all(10.0),
child: RaisedButton(
color: Colors.green,
padding: EdgeInsets.all(5.0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(4.0),
child: Icon(
Icons.send,
color: Colors.white,
),
),
Padding(
padding: const EdgeInsets.all(2.0),
child: Text(
"Enviar",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
],
),
onPressed: _enviar,
)),
Padding(
padding: const EdgeInsets.all(10.0),
child: RaisedButton(
color: Colors.redAccent,
padding: EdgeInsets.all(5.0),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(4.0),
child: Icon(
Icons.delete,
color: Colors.white,
),
),
Padding(
padding: const EdgeInsets.all(2.0),
child: Text(
"Limpar",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
],
),
onPressed: () {
_apagarTudo();
}))
],
)
],
),
);
}
}
Try these changes.
I have controlled enabled field of TextFormField. The TextFormField is disabled when you click on RaisedButton to add the item to list. And TextFormField is enabled when you click on itself.
void _addPecas() {
disableTextFormField();
...
}
bool textFormFieldEnabled = true;
void enableTextFormField(){
setState(() {
textFormFieldEnabled = true;
});
}
void disableTextFormField(){
setState(() {
textFormFieldEnabled = false;
});
}
Widget build(BuildContext context) {
....
child: TextFormField(
controller: _pecasController,
keyboardType: TextInputType.text,
enabled: textFormFieldEnabled,
onTap: () => enableTextFormField(),
style: TextStyle(
color: Colors.black,
fontSize: 18,
),
decoration: InputDecoration(
hintText: ("Adicionar item"),
),
),
...
}