I want to create an animation for every specific item in list view - flutter

I have a dynamic list view and I want to open the item when I tap on it, but when I click on it, all list items also open. I only need to open the pressed item.
I am using animated container for the animation and Visible to to hide the edit Text widget widget when the card is closed.
**Here is my code **
ListView.builder(
itemCount: dispoModes.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return Visibility(
child: GestureDetector(
onTap: () async {
setState(() {
open = !open;
});
await Future.delayed(
Duration(
milliseconds: open
? 280
: 100), () {
setState(() {
visible = !visible;
});
});
},
child: AnimatedContainer(
decoration:
const BoxDecoration(),
width: double.infinity,
height: open ? 134 : 62,
duration: const Duration(
milliseconds: 700),
curve: Curves.fastOutSlowIn,
child: Card(
shape: RoundedRectangleBorder(
side: BorderSide(
color: open
? HexColor(
'#31679A')
: Colors
.transparent,
width: open ? 2 : 0),
borderRadius:
BorderRadius.circular(
12.0),
),
elevation: 3,
child: Container(
decoration: BoxDecoration(
color:
HexColor('#F5F6F6'),
borderRadius:
const BorderRadius
.all(
Radius.circular(
12)),
border: Border.all(
color: open
? HexColor(
'#31679A')
: HexColor(
'#F5F6F6'),
width: open ? 0 : 2),
),
margin: EdgeInsets.all(
open ? 0 : 2),
child: Align(
alignment:
Alignment.topCenter,
child: Column(
children: [
Padding(
padding: EdgeInsets
.only(top: 5),
child: SizedBox(
height: 34,
child: Image.network(
"https://divadeep-admin.oxa.cloud/" +
dispoModes[index]
.imageUrl)),
),
Visibility(
visible: visible,
child: Padding(
padding:
const EdgeInsets
.fromLTRB(
25,
15,
25,
0),
child:
TextField(
keyboardType:
TextInputType
.phone,
decoration:
InputDecoration(
isDense:
true,
hintText:
'Phone Number',
hintStyle: TextStyle(
color: HexColor(
"#9B9898"),
fontSize:
17,
fontFamily:
'Segoe-UI'),
),
),
),
),
],
)),
),
),
),
),
);
}),
enter code here

Extract your list item as individual StatefulWidget to have it's own state for open and visible
class ListItem extends StatefulWidget {
ListItem({Key? key}) : super(key: key);
#override
State<ListItem> createState() => _ListItemState();
}
class _ListItemState extends State<ListItem> {
bool open = false;
bool visible = false;
#override
Widget build(BuildContext context) {
return Visibility(
child: GestureDetector(
onTap: () async {
setState(() {
open = !open;
});
await Future.delayed(Duration(milliseconds: open ? 280 : 100), () {
setState(() {
visible = !visible;
});
});
},
child: AnimatedContainer(
decoration: const BoxDecoration(),
width: double.infinity,
height: open ? 134 : 62,
duration: const Duration(milliseconds: 700),
curve: Curves.fastOutSlowIn,
child: Card(
shape: RoundedRectangleBorder(
side: BorderSide(
color: open ? HexColor('#31679A') : Colors.transparent,
width: open ? 2 : 0),
borderRadius: BorderRadius.circular(12.0),
),
elevation: 3,
child: Container(
decoration: BoxDecoration(
color: HexColor('#F5F6F6'),
borderRadius: const BorderRadius.all(Radius.circular(12)),
border: Border.all(
color: open ? HexColor('#31679A') : HexColor('#F5F6F6'),
width: open ? 0 : 2),
),
margin: EdgeInsets.all(open ? 0 : 2),
child: Align(
alignment: Alignment.topCenter,
child: Column(
children: [
Padding(
padding: EdgeInsets.only(top: 5),
child: SizedBox(
height: 34,
child: Image.network(
"https://divadeep-admin.oxa.cloud/" +
dispoModes[index].imageUrl)),
),
Visibility(
visible: visible,
child: Padding(
padding: const EdgeInsets.fromLTRB(25, 15, 25, 0),
child: TextField(
keyboardType: TextInputType.phone,
decoration: InputDecoration(
isDense: true,
hintText: 'Phone Number',
hintStyle: TextStyle(
color: HexColor("#9B9898"),
fontSize: 17,
fontFamily: 'Segoe-UI'),
),
),
),
),
],
)),
),
),
),
),
);
}
}
Then return it from your ListView as itemBuilder, like this:
ListView.builder(
itemCount: dispoModes.length,
shrinkWrap: true,
itemBuilder: (context, index) => ListItem(),
)

int selectedIndex = -1;
Widget build()
...
itemCount: dispoModes.length,
shrinkWrap: true,
itemBuilder: (context, index) {
bool open = selectedIndex == index;
return Visibility(
child: GestureDetector(
onTap: () async {
setState(() {
selectedIndex = (selectedIndex == index) ? -1 : index; // second click closes it
});
await Future.delayed(
Duration(
milliseconds: open
? 280
: 100), () {
setState(() {
// also change it here
visible = !visible;
});
});
},
child: AnimatedContainer(
decoration:
const BoxDecoration(),
width: double.infinity,
height: open ? 134 : 62,
duration: const Duration(
milliseconds: 700),
curve: Curves.fastOutSlowIn,
child: Card(
shape: RoundedRectangleBorder(
side: BorderSide(
color: open
? HexColor(
'#31679A')
: Colors
.transparent,
width: open ? 2 : 0),
borderRadius:
BorderRadius.circular(
12.0),
),
elevation: 3,
child: Container(
decoration: BoxDecoration(
color:
HexColor('#F5F6F6'),
borderRadius:
const BorderRadius
.all(
Radius.circular(
12)),
border: Border.all(
color: open
? HexColor(
'#31679A')
: HexColor(
'#F5F6F6'),
width: open ? 0 : 2),
),
margin: EdgeInsets.all(
open ? 0 : 2),
child: Align(
alignment:
Alignment.topCenter,
child: Column(
children: [
Padding(
padding: EdgeInsets
.only(top: 5),
child: SizedBox(
height: 34,
child: Image.network(
"https://divadeep-admin.oxa.cloud/" +
dispoModes[index]
.imageUrl)),
),
Visibility(
visible: visible,
child: Padding(
padding:
const EdgeInsets
.fromLTRB(
25,
15,
25,
0),
child:
TextField(
keyboardType:
TextInputType
.phone,
decoration:
InputDecoration(
isDense:
true,
hintText:
'Phone Number',
hintStyle: TextStyle(
color: HexColor(
"#9B9898"),
fontSize:
17,
fontFamily:
'Segoe-UI'),
),
),
),
),
],
)),
),
),
),
),
);
}),

Related

I want a flutter tab bar to make screen scroll to a specific location when a user click on the tab

I have 4 tabs in a flutter tab bar. I am using a silver App bar and the tab bar is inside the bottom property of the silver app bar. I have 4 containers of different sizes inside SingleChilScrollView.
The functionality I want to achieve is when a user clicks on the first tab the screen scrolls to the first container and when a user clicks on the 4th tab the screen scrolls to the 4th container and again when a user clicks on the 1st tab the screen scroll back to the first container. I will be implementing this functionality for the flutter web version.
the code is below, but the screen doesn't scroll when user clicks the tabs.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class ScrollContainerPage extends StatefulWidget {
#override
State<ScrollContainerPage> createState() => _ScrollContainerPageState();
}
class _ScrollContainerPageState extends State<ScrollContainerPage> {
ScrollController _scrollController = ScrollController();
List<GlobalKey> _globalKey = List.empty(growable: true);
late final secondContainerPosition;
late final thirdContainerPosition;
late final fourthContainerPosition;
bool initilized = false;
#override
void initState() {
for (int i = 0; i < 4; i++) {
_globalKey.add(GlobalKey());
}
super.initState();
}
getPosition() {
RenderBox box2 =
_globalKey[1].currentContext!.findRenderObject()! as RenderBox;
Offset position2 = box2.localToGlobal(Offset.zero);
if (!initilized) {
secondContainerPosition = position2.dy;
}
RenderBox box3 =
_globalKey[2].currentContext!.findRenderObject()! as RenderBox;
Offset position3 = box3.localToGlobal(Offset.zero);
if (!initilized) {
thirdContainerPosition = position3.dy;
}
RenderBox box4 =
_globalKey[3].currentContext!.findRenderObject()! as RenderBox;
Offset position4 = box4.localToGlobal(Offset.zero);
if (!initilized) {
fourthContainerPosition = position4.dy;
}
initilized = true;
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: DefaultTabController(
length: 4,
child: NestedScrollView(
floatHeaderSlivers: false,
headerSliverBuilder:
(BuildContext context, bool innerBoxIsScrolled) {
return [
SliverAppBar(
leadingWidth: 200,
centerTitle: true,
//titleSpacing: 0,
//expandedHeight: 200.0,
backgroundColor: Colors.white,
leading: const Icon(Icons.arrow_back_ios,color: Colors.black,),
title: !kIsWeb? const Text("About us",
style: TextStyle(
color: Colors.black,
fontSize: 16.0,
),
):
SizedBox(
height: 40,
width: MediaQuery.of(context).size.width*0.5,
child: Center(
child: TextField(
cursorColor: const Color.fromRGBO(0, 79, 224, 1),
//maxLines: 5,
decoration: InputDecoration(
contentPadding: const EdgeInsets.symmetric(horizontal: 20),
prefixIcon: const Icon(Icons.search),
prefixIconColor: Colors.red,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
borderSide: const BorderSide(color: Color.fromRGBO(118, 118, 128, 1), width: 2),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
borderSide: const BorderSide(color: Color.fromRGBO(118, 118, 128, 1), width: 1.5),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
borderSide: const BorderSide(color: Color.fromRGBO(0, 79, 224, 1), width: 1.5),
),
),
),
),
),
actions: kIsWeb?[
Container(
margin: const EdgeInsets.fromLTRB(12,12,80,12),
padding: const EdgeInsets.symmetric(vertical: 5,horizontal: 30),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
border: Border.all(color: const Color.fromRGBO(4, 80, 225, 1)),
),
child: InkWell(
onTap: (){
},
child: Row(
children: const [
Icon(Icons.person_outline,
color: Color.fromRGBO(4, 80, 225, 1),
),
SizedBox(width: 10,),
Text('Sign in',
style: TextStyle(
color: Color.fromRGBO(4, 80, 225, 1),
fontSize: 14.0,
// fontWeight: FontWeight.w600,
),
),
],
),
),
),
]:null,
floating: !kIsWeb?true: false,
pinned: true,
snap: !kIsWeb?true: false,
bottom: TabBar(
indicatorColor: const Color.fromRGBO(0, 79, 224, 1),
tabs: [
Tab(icon: GestureDetector(
onTap: (){
setState(() {
getPosition();
_scrollController.animateTo(
_scrollController.position.minScrollExtent,
duration: const Duration(milliseconds: 500),
curve: Curves.ease);
});
},
child: const Text('scroll to red container', style: TextStyle(color: Colors.black),)),),
Tab(icon: GestureDetector(
onTap: (){
setState(() {
getPosition();
_scrollController.animateTo(secondContainerPosition,
// !kIsWeb ? 1140 : 1000,
duration: const Duration(milliseconds: 500),
curve: Curves.ease);
});
},
child: const Text('scroll to yellow container', style: TextStyle(color: Colors.black),)),),
Tab(icon: GestureDetector(
onTap: (){
setState(() {
getPosition();
_scrollController.animateTo(thirdContainerPosition,
// !kIsWeb ? 3380 : 2000,
duration: const Duration(milliseconds: 500),
curve: Curves.ease);
});
},
child: const Text('scroll to pink container', style: TextStyle(color: Colors.black),)),),
Tab(icon: GestureDetector(
onTap: (){
setState(() {
getPosition();
_scrollController.animateTo(fourthContainerPosition,
// _scrollController.position.maxScrollExtent,
duration: const Duration(milliseconds: 500),
curve: Curves.ease);
});
},
child: const Text('scroll to pink container', style: TextStyle(color: Colors.black),)),),
]
),
),
];
},
body:
SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
key: _globalKey[0],
height: 1000,
color: Colors.red,
child: const Text('red container')
),
const SizedBox(
height: 30,
),
Container(
key: _globalKey[1],
height: 1700,
color: Colors.yellow,
child: Text('yellow Container')
),
const SizedBox(
height: 30,
),
Container(
key: _globalKey[2],
height: 3000,
color: Colors.pink,
child: Text('pink Container')
),
const SizedBox(
height: 30,
),
Container(
key: _globalKey[3],
height: 500,
color: Colors.orange,
child: Text('orangeContainer'),
),
const SizedBox(
height: 30,
),
],
),
),
),
),
);
}
}
You need to add your _scrollController to your SingleChildScrollView widget to make it work.
body : SingleChildScrollView(
controller: _scrollController, //just add this line
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
key: _globalKey[0],
height: 1000,
color: Colors.red,
child: const Text('red container')),
const SizedBox(
height: 30,
),
Container(
key: _globalKey[1],
height: 1700,
color: Colors.yellow,
child: Text('yellow Container')),
const SizedBox(
height: 30,
),
Container(
key: _globalKey[2],
height: 3000,
color: Colors.pink,
child: Text('pink Container')),
const SizedBox(
height: 30,
),
Container(
key: _globalKey[3],
height: 500,
color: Colors.orange,
child: Text('orangeContainer'),
),
const SizedBox(
height: 30,
),
],
),
),

How can I controll the position of the listview?

I have a widget that user can add item to the listview above(like tags), I want Listview.builder to show always last item of the list, when the user add more item to the list, How can I provide it ?.........................................
.......................................................................................................
#override
Widget build(BuildContext context) {
List<Ingredient> _ingredients = Provider.of<IngredientsProvider>(context, listen: true).selectedIngredients;
return AnimatedPadding(
duration: Duration(milliseconds: 500),
curve: Curves.linearToEaseOut,
padding:EdgeInsets.only(top: _top,right: _right,left: _left,bottom: _bottom),
child: AnimatedContainer(
height:_animatedContainerHeight,
duration: Duration(milliseconds: 500),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
border:Border.all(style: BorderStyle.solid, width: 1),
color: Colors.white,
borderRadius: BorderRadius.circular(90),
),
height: 60,
child: TextField(
style: TextStyle(
color: Colors.black,
fontFamily:"OpenSans",
fontSize: 20,
),
textAlign: TextAlign.center,
textAlignVertical: TextAlignVertical.center,
onChanged: (value){
if(value.length>0){
value=value[0].toUpperCase()+value.substring(1);
filterSearchResults(value);
}
else{
filterSearchResults(value);
}
},
decoration: InputDecoration(
prefixIcon: Icon(Icons.search),
border:OutlineInputBorder(
borderRadius: BorderRadius.circular(90),
borderSide: BorderSide(
color: kColorTheme10,
),
),
hintText: "Malzeme ismi arayın",
hintStyle: TextStyle(
color: Colors.black.withOpacity(0.5),
fontFamily: "OpenSans",
),
),
),
),
SizedBox(height: 2,),
Expanded(
flex: _animatedContainerHeight==350?1:4,
child: ListView.builder(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
itemCount: _ingredients.length,
itemBuilder: (context,index){
return Padding(
padding: EdgeInsets.all(1),
child: GestureDetector(
onTap: (){
setState(() {
removeIngredient(_ingredients[index],context);
if (_ingredients.length == 0) {
_toggleCardHeight();
_toggleCardSize();
}
}
);
},
child: Container(
decoration: BoxDecoration(
color: kColorTheme11,
borderRadius: BorderRadius.circular(90),
border: Border.all(style: BorderStyle.solid,width: 1),
),
child: Padding(
padding: EdgeInsets.all(8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
BorderedText(strokeColor: Colors.black,strokeWidth: 2,child: Text(_ingredients[index].ingredientName,style:
TextStyle(fontWeight: FontWeight.bold,fontSize:20,color: Colors.white),)),
SizedBox(width: 5,),
Icon(
Icons.cancel,color: Colors.white,size: 20,
),
],
),
),
),
),
);
}
),
),
SizedBox(height: 2,),
Expanded(
flex: 40,
child: ListView.builder(
shrinkWrap: true,
itemCount: items.length,
itemBuilder: (context, index) {
return Padding(
padding: EdgeInsets.all(2.0),
child: GestureDetector(
onTap: ()async{
if(_ingredients.length==0){
Ingredient ingredient=Ingredient(ingredientName:"${items[index]}",dropDownValue: "Çay Kaşığı",ingredientAmount: null);
addIngredient(ingredient,context);
_toggleCardHeight();
_toggleCardSize();
setState(() {});
}
else{
for(var i in _ingredients){
if(i.ingredientName==items[index]){
var response= await showAlertDialog(context);
if (response!=true){
setState(() {});
}
}
else {
Ingredient ingredient=Ingredient(ingredientName:"${items[index]}",dropDownValue: "Çay Kaşığı",ingredientAmount: null);
addIngredient(ingredient,context);
setState(() {});
}
}
}
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(90),
border: Border.all(style:BorderStyle.solid,width: 1),
color: Colors.white54,
),
child: Padding(
padding: EdgeInsets.all(5),
child: Text('${items[index]}',style: TextStyle(fontWeight: FontWeight.bold),)),
),
),
);
},
),
),
],
),
),
decoration: BoxDecoration(
border: Border.all(style: BorderStyle.solid, width: 1),
borderRadius: BorderRadius.circular(30),
color:categoryModels[widget.subCategoryId].subCategoryModels[widget.subCategoryCardId].categoryColor.withOpacity(0.5),
)
),
);
}
}
To control the position, you have to manage the controller of the ListView.
Here's a theoretical example:
final _controller = ScrollController();
#override
Widget build(BuildContext context) {
return ListView.builder(
controller: _controller,
itemCount: 100,
itemBuilder: (_, __) => ListTile(title: Text('Some Text')),
);
}
Then if you want to smoothly go to the last position, do something like:
_controller.animateTo(
_controller.position.maxScrollExtent,
duration: Duration(seconds: 1),
curve: Curves.easeOut,
);

Flutter How to get value from a custom widget

I have a container that color can change using a color list. I want to get the selected color of the container from the main page. When the container clicked, a list of colors appears and we can select the color for the container. I want to do is to get the color value from that container when I press a button
Widget build(BuildContext context) {
return Container(
height: 80,
width: 40,
padding: EdgeInsets.all(5),
child: InkWell(
onTap: () {
showDialog(
context: context,
child: Dialog(
backgroundColor: Colors.white,
// insetPadding: EdgeInsets.all(100),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
child: Column(
children: [
Container(
color: Colors.red,
height: 50,
alignment: Alignment(0, 0),
child: Text(
'Select the Color',
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 20),
),
),
ListView.builder(
shrinkWrap: true,
itemCount: colors.length,
itemBuilder: (context, index) {
return GestureDetector(
child: Container(
decoration: BoxDecoration(
//border: Border.all(),
),
padding: EdgeInsets.all(5),
child: Row(
children: <Widget>[
SizedBox(
width: 20,
),
Container(
decoration: BoxDecoration(
boxShadow: <BoxShadow>[
BoxShadow(blurRadius: 10)
],
border: Border.all(),
borderRadius:
BorderRadius.circular(100),
color: color[index]),
padding: EdgeInsets.all(5),
//color: color[index],
height: 45,
width: 45,
),
Padding(
padding: EdgeInsets.all(10),
),
Text(
colors[index],
style: TextStyle(
fontFamily:
GoogleFonts.inter().fontFamily,
color: color[index],
fontSize: 20.0,
shadows: [
Shadow(
// bottomLeft
offset: Offset(0, 1.5),
blurRadius: 5,
color: Colors.black),
],
),
),
],
),
),
onTap: () {
Navigator.pop(context);
setState(() {
selectedColor = color[index];
print(index);
});
},
);
})
],
)),
);
},
child: Container(
padding: EdgeInsets.all(10),
width: 20,
height: 60,
decoration: BoxDecoration(
color: selectedColor,
borderRadius: BorderRadius.circular(10),
),
),
),
);
}
You can pass the value to parent when you call Navigator.pop().
https://flutter.dev/docs/cookbook/navigation/returning-data
onTap: () {
Navigator.pop(context, color[index]);
setState(() {
selectedColor = color[index];
print(index);
});
},
In this case, you need to wait for result after call Navigator push method.
final result = await Navigator.push(
...

How to have the text from a selected item inside a text field in flutter

I have an edit function which displays in a dialog in my to do list app on flutter. When an item is selected to be edited, a dialog containing a TextField(to enter the new value of the selected item) and a button(to save the changes) appears. The goal is to have the text of the selected item on the TextField of the dialog, currently my code has a hintText inside the TextField that does display the value of the selected item but what I want to achieve is to have that in the controller.
If you didnt understood what I want to achieve see this edit function like instagram's one, when editing a post on instagram you don't have to type everything again instead when editing you have the original text of the post there. Well that is not happening on my app, when editing an item the TextField doesnt show anything. How can I make this work?
code related to the edit function
List<ToDoElement> _toDoItems = [];
TextEditingController _editController = TextEditingController();
void _editToDoItem(String newText, int index) {
setState(() {
_toDoItems[index].task = newText;
});
}
_editDialog(BuildContext context, int index) {
return showDialog(context: context, builder: (context){
return Dialog(
backgroundColor: Colors.transparent,
insetAnimationDuration:
const Duration(milliseconds: 800),
child: Container(
padding: EdgeInsets.all(20),
height: 180,
width: 100,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 60,
child: TextField( // this is the textfield that I should have the text of the selected item inside.
controller: _editController,
autofocus: true,
autocorrect: false,
onSubmitted: (val) {
FocusScope.of(context).requestFocus(FocusNode());
_editToDoItem(val, index);
Navigator.of(context).pop();
},
decoration: InputDecoration(
hintText: '${_toDoItems[index].task}', //this hint text shows the value of the selected item, yhis is what I want to have but in the controller.
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
),
)
),
Container(
height: 65,
width: double.infinity,
margin: EdgeInsets.only(top: 5,),
child: RaisedButton(
textColor: Colors.white,
color: Colors.red,
child: Text('EDIT', style: TextStyle(fontSize: 18)),
onPressed: () {
_editToDoItem(_editController.text, index);
FocusScope.of(context).requestFocus(FocusNode());
Navigator.of(context).pop();
},
),
),
],
),
),
);
});
}
full main.dart
import 'package:flutter/material.dart';
class ToDoElement {
String task;
final DateTime timeOfCreation;
ToDoElement(this.task, this.timeOfCreation);
}
void main() => runApp(MaterialApp(home: MyApp()));
class MyApp extends StatefulWidget {
#override
createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
List<ToDoElement> _toDoItems = [];
TextEditingController _controller = TextEditingController();
TextEditingController _editController = TextEditingController();
void _addToDoItem(String task) {
if(task.isNotEmpty) {
setState(() {
_toDoItems.add(ToDoElement(task, DateTime.now()));
});
}
}
void _editToDoItem(String newText, int index) {
setState(() {
_toDoItems[index].task = newText;
});
}
void _removeTodoItem(int index) {
setState(() => _toDoItems.removeAt(index));
}
_editDialog(BuildContext context, int index) {
return showDialog(context: context, builder: (context){
return Dialog(
backgroundColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)
),
insetAnimationDuration:
const Duration(milliseconds: 800),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(20.0)),
),
padding: EdgeInsets.all(20),
height: 180,
width: 100,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 60,
child: TextField(
controller: _editController,
autofocus: true,
autocorrect: false,
onSubmitted: (val) {
FocusScope.of(context).requestFocus(FocusNode());
_editToDoItem(val, index);
Navigator.of(context).pop();
},
style: TextStyle(fontSize: 17,),
decoration: InputDecoration(
hintText: '${_toDoItems[index].task}',
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
),
)
),
Container(
height: 65,
width: double.infinity,
margin: EdgeInsets.only(top: 5,),
child: RaisedButton(
textColor: Colors.white,
color: Colors.red,
child: Text('EDIT', style: TextStyle(fontSize: 18)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),
),
onPressed: () {
_editToDoItem(_editController.text, index);
FocusScope.of(context).requestFocus(FocusNode());
Navigator.of(context).pop();
},
),
),
],
),
),
);
});
}
Widget _buildToDoItem(String toDoText, int index) {
return SizedBox(
child: Container(
height: 58,
margin: EdgeInsets.only(left: 22.0, right: 22.0, bottom: 12,),
decoration: BoxDecoration(
border: Border.all(width: 1.5, color: Colors.red),
borderRadius: BorderRadius.all(Radius.circular(18)),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children:[
Expanded(
child: ListTile(
title: Text(
toDoText,
style: TextStyle(fontSize: 18),
),
onTap: () => null,
),
),
FlatButton(
child: Text('Edit', style: TextStyle(color: Colors.red, fontSize: 16.5),),
onPressed: () => _editDialog(context, index),
),
FlatButton(
child: Text('Delete', style: TextStyle(color: Colors.red, fontSize: 16.5),),
onPressed: () => _removeTodoItem(index),
),
],
),
),
);
}
int compareElement(ToDoElement a, ToDoElement b) =>
a.timeOfCreation.isAfter(b.timeOfCreation) ? -1 : 1;
Widget _buildToDoList() {
_toDoItems.sort(compareElement);
return Expanded(
child: ListView.builder(
itemCount: _toDoItems.length,
itemBuilder: (context, index) {
if (index < _toDoItems.length) {
return _buildToDoItem(_toDoItems[index].task, index);
}
},
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(50),
child: AppBar(
centerTitle: true,
backgroundColor: Colors.red,
title: Text('To Do List', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold,),),
)
),
backgroundColor: Colors.white,
body: GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 60,
margin: EdgeInsets.all(22),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
flex: 10,
child: Container(
height: double.infinity,
child: TextField(
controller: _controller,
autofocus: true,
onSubmitted: (val) {
_addToDoItem(val);
_controller.clear();
},
style: TextStyle(fontSize: 18,),
decoration: InputDecoration(
hintText: 'Add a task here...',
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
),
),
),
),
Expanded(
flex: 4,
child: Container(
height: double.infinity,
margin: EdgeInsets.only(left: 12),
child: RaisedButton(
textColor: Colors.white,
color: Colors.red,
child: Text('ADD', style: TextStyle(fontSize: 18)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),
),
onPressed: () {
_addToDoItem(_controller.text);
_controller.clear();
FocusScope.of(context).requestFocus(FocusNode());
},
),
),
),
],
),
),
_buildToDoList()
]
),
),
);
}
}
If you have any questions please let me know in the comments;)
You already have the _editController variable. You can use it not only to get the typed text but also to set it:
You can do it before calling the edit function, for example:
[...]
onPressed: () {
_editController.text = toDoText;
_editDialog(context, index);
},
[...]
(Or maybe before creating the dialog, if you prefer.)
As you can see in the documentation:
A TextEditingController can also be used to provide an initial value for a text field. If you build a text field with a controller that already has text, the text field will use that text as its initial value.

Enable and disable a button in flutter

import 'package:flutter/material.dart';
class BidContainer extends StatefulWidget {
final name;
BidContainer({this.name});
#override
_BidContainerState createState() => _BidContainerState();
}
class _BidContainerState extends State<BidContainer> {
bool _active = false;
void handleTap() {
setState(() {
_active = !_active;
});
}
#override
Widget build(BuildContext context) {
var names = widget.name;
return GestureDetector(
onTap: () {
setState(() {
print('$names');
_active = !_active;
});
},
child: Container(
margin: EdgeInsets.all(8),
height: 30,
width: 50,
child: Center(
child: Text(
'$names',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 15,
),
),
),
decoration: BoxDecoration(
color: _active ? Colors.deepPurpleAccent : Colors.white,
borderRadius: BorderRadius.circular(15),
border: Border.all(
color: Colors.deepPurpleAccent,
width: 1.2,
),
),
),
);
}
}
I am trying to make this button active and inactive but i am able to do this with my code which is this container which i have called with the GridView() once i tap to these container it is selected but when i scroll upward or downward after selecting to these container become unselected
Container(
height: 500,
width: 380,
decoration: BoxDecoration(
border: Border.all(
width: 4,
color: Colors.black,
),
),
child: GridView(
children: BID_DATA
.map((bidValue) => BidContainer(
name: bidValue,
))
.toList(),
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 70,
childAspectRatio: 3 / 2,
crossAxisSpacing: 5,
mainAxisSpacing: 5,
),
),
),
This is the container where i have called that Container for which i have provided the code above and BID_DATA is a list of those numbers that are showing in that contaner.
child: GridView.builder(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 70,
childAspectRatio: 3 / 2,
crossAxisSpacing: 5,
mainAxisSpacing: 5,
),
itemBuilder: (BuildContext context, int index) => Container(
decoration: BoxDecoration(
color: item[index] ? Colors.deepPurpleAccent : Colors.white,
borderRadius: BorderRadius.circular(15),
border: Border.all(
color: Colors.deepPurpleAccent,
width: 1.2,
),
),
margin: EdgeInsets.all(
5
),
height: 30,
width: 30,
child: FlatButton(
onPressed: () {
setState(() {
item[index] = !item[index];
});
},
child: Center(
child: Text(
'${BID_DATA[index]}',
style: TextStyle(
color: item[index] ? Colors.white : Colors.black,
fontWeight: FontWeight.bold,
fontSize: 15,
),
),
),
),
),
),