Sliver AppBar not collapse when using listviewbuilder - flutter

im so confuse why my sliverappbar doesnt collapse when i'm scrolling listviewbuilder
so what i want is Appbar will colapse but the bottom is pinned, also when im scrolling to up the appbar will show'n
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
pinned: true,
snap: true,
floating: true,
expandedHeight: 150,
centerTitle: true,
title: Text('mama'),
bottom: AppBar(
title: Container(
height: 45,
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: 'Enter a search term'),
),
),
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
height: MediaQuery.of(context).size.height,
child: StreamBuilder<ListsetorModel>(
stream: con.resListsetor.stream,
builder: (_, snapshot) {
if (snapshot.hasData) {
if (snapshot.data!.result == null) {
return Center(
child: Text('Data kosong '),
);
} else {
return Scrollbar(
thickness: 5,
child: ListView.builder(
itemCount: snapshot.data!.result!.length,
itemBuilder: (context, index) {
var formatDate = DateFormat('yyyy-MM-dd ')
.format(snapshot
.data!.result![index].createdAt!
.toLocal());
Result list =
snapshot.data!.result![index];
return InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
DetailTransaksi(
kode: list.kode)));
},
child: Container(
child: Card(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(9.0),
),
child: Container(
child: Padding(
padding:
const EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Container(
child: Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Text(
"Order ${list.kode}",
style: TextStyle(
fontWeight:
FontWeight
.bold),
),
Text(formatDate),
],
),
),
Divider(),
Text(
"Please help us to confirm \nto get 10% discount code for next order."),
SizedBox(
height: 10,
),
Container(
child: Row(
mainAxisAlignment:
MainAxisAlignment
.spaceBetween,
children: [
Container(
width: 96,
height: 36,
color: Color(
0xff85d057),
child: TextButton(
child: Row(
children: [
SizedBox(
width: 5,
),
Text(
"Qr Code",
style: TextStyle(
color: Colors
.white),
),
SizedBox(
height: 20,
width: 20,
child: Image
.asset(
'assets/images/qrscan.png'),
)
],
),
onPressed: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => Qrcode(
data: list.kode!,
)));
},
),
),
)
],
),
),
],
),
),
),
),
),
);
}),
);
}
}
return Center(child: CircularProgressIndicator());
}),
);
},
),
),
],
),
),
);
}
so i want the sliverappbar collapse when im scroll thi listview, i tried adding physics neverscrollable on listview builder it doesn't work properly

so the answer is by adding in NestedScrollview
floatHeaderSlivers: true,
and remove snap: true inside sliverappbar

Please refer to below code
class AnimatedAppBar extends StatefulWidget {
const AnimatedAppBar({Key key}) : super(key: key);
#override
_AnimatedAppBarState createState() => _AnimatedAppBarState();
}
class _AnimatedAppBarState extends State<AnimatedAppBar>
with TickerProviderStateMixin {
final TextEditingController stateController = TextEditingController();
final FocusNode stateFocus = FocusNode();
var animation;
var controller;
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: NestedScrollView(
headerSliverBuilder:
(BuildContext context, bool innnerBoxIsScrolled) {
if (innnerBoxIsScrolled) {
/* Animation */
controller = AnimationController(
vsync: this,
duration: Duration(
seconds: 1,
),
);
animation = Tween(
begin: 0.0,
end: 1.0,
).animate(controller);
/* Animation */
controller.forward();
}
return <Widget>[
SliverAppBar(
expandedHeight: 120.0,
floating: false,
pinned: true,
backgroundColor: Colors.grey,
automaticallyImplyLeading: false,
titleSpacing: 0.0,
toolbarHeight: 90.0,
centerTitle: false,
elevation: 0.0,
leadingWidth: 0.0,
title: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
if (innnerBoxIsScrolled != null &&
innnerBoxIsScrolled == true)
FadeTransition(
opacity: animation,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: 10.0,
),
Text(
"Search",
style: TextStyle(
color: Colors.black,
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
autovalidateMode:
AutovalidateMode.onUserInteraction,
/* autovalidate is disabled */
controller: stateController,
inputFormatters: [
FilteringTextInputFormatter.deny(
RegExp(r"\s\s")),
FilteringTextInputFormatter.deny(RegExp(
r'(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])')),
],
keyboardType: TextInputType.text,
maxLength: 160,
onChanged: (val) {},
maxLines: 1,
validator: (value) {},
focusNode: stateFocus,
autofocus: false,
decoration: InputDecoration(
errorMaxLines: 3,
counterText: "",
filled: true,
fillColor: Colors.white,
focusedBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Color(0xffE5E5E5),
),
),
disabledBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Color(0xffE5E5E5),
),
),
enabledBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Color(0xffE5E5E5),
),
),
border: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
),
),
errorBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Colors.red,
)),
focusedErrorBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Colors.red,
),
),
hintText: "Search" ?? "",
),
),
),
SizedBox(
height: 6.0,
)
],
),
),
],
),
// bottom: PreferredSize(
// preferredSize: Size.fromHeight(5.0),
// child: Text(''),
// ),
flexibleSpace: FlexibleSpaceBar(
background: Container(
width: MediaQuery.of(context).size.width,
child: Stack(
alignment: Alignment.center,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
height: 10.0,
),
Padding(
padding: EdgeInsets.symmetric(
horizontal: 8.0,
),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
"Search",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 24.0,
),
),
CircleAvatar(
backgroundImage: NetworkImage(
"https://images.ctfassets.net/hrltx12pl8hq/2TRIFRwcjrTuNprkTQHVxs/088159eb8e811aaac789c24701d7fdb1/LP_image.jpg?fit=fill&w=632&h=354&fm=webp"), //NetworkImage
radius: 16.0,
),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
autovalidateMode:
AutovalidateMode.onUserInteraction,
/* autovalidate is disabled */
controller: stateController,
inputFormatters: [
FilteringTextInputFormatter.deny(
RegExp(r"\s\s")),
FilteringTextInputFormatter.deny(RegExp(
r'(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])')),
],
keyboardType: TextInputType.text,
maxLength: 160,
onChanged: (val) {},
maxLines: 1,
validator: (value) {},
focusNode: stateFocus,
autofocus: false,
decoration: InputDecoration(
errorMaxLines: 3,
counterText: "",
filled: true,
fillColor: Colors.white,
focusedBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Color(0xffE5E5E5),
),
),
disabledBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Color(0xffE5E5E5),
),
),
enabledBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Color(0xffE5E5E5),
),
),
border: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
),
),
errorBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Colors.red,
)),
focusedErrorBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(4)),
borderSide: BorderSide(
width: 1,
color: Colors.red,
),
),
hintText: "Search" ?? "",
),
),
),
],
),
],
),
),
),
),
];
},
body: Builder(
builder: (BuildContext context) {
return SingleChildScrollView(
child: Column(
children: [
ListView.builder(
itemCount: 100,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(4.0),
child: Text("Index value: $index"),
);
},
)
],
),
);
},
),
),
),
);
}
}
Nested Scroll with Tab Bar
class NestedScrollWithTabs extends StatefulWidget {
const NestedScrollWithTabs({Key key}) : super(key: key);
#override
_NestedScrollWithTabsState createState() => _NestedScrollWithTabsState();
}
class _NestedScrollWithTabsState extends State<NestedScrollWithTabs>
with TickerProviderStateMixin {
var animation;
var controller;
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: DefaultTabController(
length: 2,
child: NestedScrollView(
physics: NeverScrollableScrollPhysics(),
headerSliverBuilder: (headerCtx, innnerBoxIsScrolled) {
if (innnerBoxIsScrolled) {
/* Animation */
controller = AnimationController(
vsync: this,
duration: Duration(
seconds: 1,
),
);
animation = Tween(
begin: 0.0,
end: 1.0,
).animate(controller);
/* Animation */
controller.forward();
}
return <Widget>[
SliverAppBar(
expandedHeight: ScreenUtil().setHeight(185.0),
floating: false,
pinned: true,
backgroundColor: Colors.white,
automaticallyImplyLeading: false,
titleSpacing: 0.0,
centerTitle: true,
elevation: 0.0,
leadingWidth: 0.0,
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
if (innnerBoxIsScrolled != null &&
innnerBoxIsScrolled == true)
FadeTransition(
opacity: animation,
child: Text(
"Title",
style: TextStyle(
color: Colors.black,
fontSize: 22,
fontWeight: FontWeight.bold,
),
),
),
],
),
flexibleSpace: FlexibleSpaceBar(
background: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(
alignment: Alignment.center,
clipBehavior: Clip.none,
children: [
Image.network(
"https://images.pexels.com/photos/10181294/pexels-photo-10181294.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500" ??
"",
fit: BoxFit.fitWidth,
height: ScreenUtil().setHeight(126.0),
width: ScreenUtil().screenWidth,
filterQuality: FilterQuality.low,
loadingBuilder: (BuildContext context,
Widget child,
ImageChunkEvent loadingProgress) {
if (loadingProgress == null) return child;
return Container(
height: ScreenUtil().setHeight(126.0),
width: ScreenUtil().screenWidth,
color: Colors.grey,
);
},
errorBuilder: (context, error, stackTrace) {
return SizedBox(
height: ScreenUtil().setHeight(126.0),
width: ScreenUtil().screenWidth,
child: Container(
width: ScreenUtil().screenWidth,
),
);
},
),
Positioned(
top: ScreenUtil().setHeight(92.0),
// left: ScreenUtil().setWidth(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
CircleAvatar(
backgroundColor: Colors.transparent,
radius: 30.0,
child: ClipRRect(
borderRadius: BorderRadius.circular(
45.0,
),
child: Image.network(
"https://images.pexels.com/photos/10181294/pexels-photo-10181294.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500" ??
"",
fit: BoxFit.fill,
height: ScreenUtil().setHeight(72.0),
width: ScreenUtil().screenWidth,
filterQuality: FilterQuality.low,
loadingBuilder: (BuildContext context,
Widget child,
ImageChunkEvent loadingProgress) {
if (loadingProgress == null)
return child;
return Container(
height:
ScreenUtil().setHeight(72.0),
width: ScreenUtil().screenWidth,
color: Colors.grey,
);
},
errorBuilder:
(context, error, stackTrace) {
return SizedBox(
height:
ScreenUtil().setHeight(72.0),
width: ScreenUtil().screenWidth,
child: Container(
width: ScreenUtil().screenWidth,
),
);
},
),
),
),
Text("Name"),
Text("Place"),
],
),
),
],
),
],
),
),
),
SliverOverlapAbsorber(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
headerCtx),
sliver: SliverPersistentHeader(
delegate: SliverAppBarDelegate(TabBar(
labelColor: Colors.blue,
unselectedLabelColor: Colors.black,
labelStyle: TextStyle(
fontSize: 15.0,
),
unselectedLabelStyle: TextStyle(
fontSize: 15.0,
),
labelPadding: EdgeInsets.zero,
indicatorColor: Colors.blue,
indicatorPadding: EdgeInsets.zero,
physics: NeverScrollableScrollPhysics(),
tabs: [
Tab(
text: "Tab 1",
),
Tab(
text: "Tab 2",
),
],
)),
pinned: false,
),
),
];
},
body: TabBarView(
children: [
/* Tab 1 */
Container(
color: Colors.white,
child: ListView.builder(
itemCount: 100,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(4.0),
child: Text("Index value: $index"),
);
},
),
),
/* Tab 2 */
Container(
color: Colors.white,
child: ListView.builder(
itemCount: 10,
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: const EdgeInsets.all(4.0),
child: Text("Index value of Tab 2: $index"),
);
},
),
),
],
),
),
),
),
);
}
}
class SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
SliverAppBarDelegate(this.tabBars);
final TabBar tabBars;
#override
double get minExtent => 60.0;
#override
double get maxExtent => 60.0;
#override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
// shinkOffsetPerValue.value = shrinkOffset;
return new Container(
color: Colors.white,
child: Column(
children: [
tabBars,
],
),
);
}
#override
bool shouldRebuild(SliverAppBarDelegate oldDelegate) {
return false;
}
}

Related

flutter A RenderFlex overflowed by 271 pixels on the bottom

Hello I am using SingleChildScrollView and I am getting this error 'A RenderFlex is overflowing with 271 pixels at the bottom'. I think it's because you're using the appBar's PreferredSize and tabBarview. Sorry for the long code.
A widget that uses a abbar tabbarView.
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: PreferredSize(
preferredSize: Size.fromHeight(kToolbarHeight),
child: Container(
color: Colors.black,
child: SafeArea(
child: Column(
children: [
TabBar(
indicatorColor: Colors.grey,
controller: this._tabController,
tabs: [
Tab(
text: 'MOVIE',
),
Tab(
text: 'TV',
),
],
),
],
)),
),
),
// bottom:
body: TabBarView(
controller: this._tabController,
children: [
Column(
children: [
search(),
this.movieName.isNotEmpty ? searchMovieTile() : Container(),
],
),
Column(
children: [
search(),
this.movieName.isNotEmpty ? searchTvTile() : Container(),
],
)
],
),
);
}
A widget that uses a SingleChildScrollView.
Widget searchMovieTile() {
return FutureBuilder(
future: this._searchController.searchMovie(movieName: this.movieName),
builder:
(BuildContext context, AsyncSnapshot<List<SearchModel>> snapshot) {
if (snapshot.hasData) {
return Consumer<SearchProvider>(
builder: (context, value, child) {
return snapshot.data!.isEmpty
? Container()
: SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height,
child: GridView.count(
childAspectRatio: 2 / 3,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
crossAxisCount: 3,
children: List.generate(
snapshot.data!.length,
(index) => ClipRRect(
borderRadius: BorderRadius.circular(15.0),
child: snapshot.data![index].posterPath.isEmpty
? Container(
child: Center(
child: Text(
'Image preparation',
style: TextStyle(color: Colors.white),
),
),
)
: GestureDetector(
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(builder:
(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (BuildContext
context) =>
MovieDetailProvider()),
ChangeNotifierProvider(
create:
(BuildContext context) =>
MovieVideoProvider()),
],
child: SearchMovieDetailScreen(
movieData:
snapshot.data![index]),
);
}));
},
child: CachedNetworkImage(
fit: BoxFit.cover,
imageUrl:
'https://image.tmdb.org/t/p/original/${snapshot.data![index].posterPath}',
),
),
),
),
),
),
);
},
);
} else {
return Container();
}
},
);
}
A widget that uses a textfield keyboard.
Widget search() {
return Container(
padding: EdgeInsets.only(
left: 5.0,
top: 10.0,
right: 5.0,
bottom: 10.0,
),
child: Row(
children: [
Expanded(
flex: 6,
child: TextField(
onSubmitted: (String name) {
this.movieName = this._textEditingController.text;
print(this.movieName);
},
cursorColor: Colors.grey,
focusNode: this._focusNode,
style: TextStyle(
color: Colors.white,
fontSize: 15.0,
),
controller: this._textEditingController,
decoration: InputDecoration(
filled: true,
fillColor: Colors.grey[900],
prefixIcon: Icon(
Icons.search,
color: Colors.grey,
size: 20.0,
),
suffixIcon: this._focusNode.hasFocus
? IconButton(
onPressed: () {
setState(() {
this._textEditingController.clear();
});
},
icon: Icon(
Icons.cancel,
size: 20.0,
color: Colors.grey,
),
)
: Container(),
hintText: 'Search',
hintStyle: TextStyle(color: Colors.grey),
labelStyle: TextStyle(color: Colors.white),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.transparent,
),
borderRadius: BorderRadius.circular(10.0),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.transparent,
),
borderRadius: BorderRadius.circular(10.0),
),
border: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.transparent,
),
borderRadius: BorderRadius.circular(10.0),
),
),
),
),
this._focusNode.hasFocus
? Expanded(
child: TextButton(
child: Text(
'cancel',
style: TextStyle(
fontSize: 13.0,
color: Colors.grey,
),
),
onPressed: () {
setState(() {
this._textEditingController.clear();
this._focusNode.unfocus();
});
},
))
: Expanded(flex: 0, child: Container())
],
),
);
}
Sorry for the low level of the question, but I'd appreciate it if you could answer :)
I think this problem is due to the given height to the container (child of SingleChildScrollView:
SingleChildScrollView(
child: Container(
**height: MediaQuery.of(context).size.height,**
child: GridView.count(
just remove it and let me know the result.
try : height: MediaQuery.of(context).size.height - 280,

How to wrap showModalBottomSheet in SafeArea? - Flutter

I am using a textformfield in the bottomsheet, when the keyboard is opened, the sheet is going out of safe Area, is there anyway we can wrap bottomsheet in safeArea? I tried wrapping the bottomsheet child into safeArea, but it didn't work.
When the keyboard closed:
Code:
onPressed: () {
showModalBottomSheet(
isScrollControlled: true,
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10),
topRight: Radius.circular(10))),
builder: (context) {
return Padding(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context)
.viewInsets
.bottom),
child: Container(
margin: EdgeInsets.only(
top: MediaQuery.of(context)
.viewPadding
.top),
height:
MediaQuery.of(context).size.height *
0.65,
child:
SinglePostScreen(postID: posts.id)),
);
});
}
The screen that displays in bottomsheet (while keyboard opened):
Code:
class SinglePostScreen extends StatefulWidget {
final String postID;
SinglePostScreen({#required this.postID});
#override
_SinglePostScreenState createState() => _SinglePostScreenState();
}
class _SinglePostScreenState extends State<SinglePostScreen> {
final ConstantColors constantColors = ConstantColors();
Future<SinglePost> singlePost;
Future<UserProfileModel> userProfileModel;
TextEditingController commentCont = TextEditingController();
#override
void initState() {
super.initState();
singlePost = SinglePostServices().singlePost(widget.postID);
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: SingleChildScrollView(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10), topRight: Radius.circular(10))),
child: Container(
child: Column(
children: [
Divider(
color: Colors.black45,
thickness: 2.5,
indent: 150,
endIndent: 150,
),
Container(
height: MediaQuery.of(context).size.height * 0.55,
child: FutureBuilder<SinglePost>(
future: singlePost,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
if (snapshot.data.comments.length == 0) {
return Text(
"no data yet",
style: TextStyle(color: Colors.black),
);
}
if (snapshot.connectionState == ConnectionState.done) {
return Container(
child: ListView.builder(
itemCount: snapshot.data.comments.length,
itemBuilder: (context, index) {
var comments = snapshot.data.comments[index];
return Container(
child: Column(
children: [
FutureBuilder<UserProfileModel>(
future: userProfileModel =
UserProfileServices()
.getUserProfile(
comments.userId),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Provider.of<
SinglePageHelpers>(
context,
listen: false)
.comment(
context,
"https://source.unsplash.com/random",
"${snapshot.data.firstname} ${snapshot.data.lastname}",
timeago.format(comments
.createdAt
.toLocal()),
comments.comment);
} else {
return Center(
child:
CircularProgressIndicator());
}
},
),
],
),
);
}),
);
}
},
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Padding(
padding: const EdgeInsets.all(4.0),
child: Container(
width: MediaQuery.of(context).size.width * 0.7,
height: MediaQuery.of(context).size.height * 0.06,
child: TextFormField(
maxLines: 5,
minLines: 1,
cursorHeight: 15,
cursorColor: constantColors.purple,
cursorWidth: 1,
controller: commentCont,
textAlign: TextAlign.left,
style: TextStyle(color: Colors.black),
decoration: InputDecoration(
hintText: "add comment",
contentPadding: EdgeInsets.all(8.0),
hintStyle:
TextStyle(color: Colors.black, height: 1.4),
fillColor: Colors.grey[200],
filled: true,
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.transparent,
)),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.transparent,
))),
),
),
),
RawMaterialButton(
fillColor: constantColors.purple,
constraints: BoxConstraints.tight(Size(75, 35)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5)),
onPressed: () {},
child: Text(
"comment",
style: TextStyle(color: Colors.white),
),
)
],
)
],
),
),
),
),
);
}
}

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,
);

The getter 'visible' was called on null

I am trying to create a page that consist of Search Bar, Infinite scroll product page and buttons (add product, remove product and notification). There is an error for the below statement...
The getter 'visible' was called on null,
Receiver : null,
Tried calling : null
please help me in rectifying this code.
class Inventory extends StatefulWidget {
#override
_InventoryState createState() => _InventoryState();
}
class _InventoryState extends State<Inventory> {
Color _color = Colors.white;
#override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: PreferredSize(
preferredSize: Size.fromHeight(70),
child: AppBar(
backgroundColor: Theme.Colors.darkBlue,
iconTheme: IconThemeData(size: 10, color: Colors.white),
elevation: 0,
title: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
AutoSizeText(
"Inventory ",
style: TextStyle(
fontSize: 35,
),
),
],
)),
),
drawer: MainDrawer(),
backgroundColor: Color(0xFF09182C),
body: Center(
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Container(
height: 70,
width: width * 0.76,
child: TextField(
decoration: InputDecoration(
contentPadding: EdgeInsets.all(10.0),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.white),
),
hintText: 'Search Inventory',
hintStyle:
TextStyle(color: Color(0xFFE0E0E0), fontSize: 20),
suffixIcon: Icon(
Icons.search,
color: Colors.white,
size: 30,
)),
style: TextStyle(color: _color),
),
),
Container(
padding: EdgeInsets.only(bottom: 30.0),
child: IconButton(
onPressed: () {},
icon: Icon(Icons.filter_list,
size: 40, color: Color(0xFFFFAE40)),
),
),
],
),
LoadingPage(),
Spacer(),
Container(
margin: EdgeInsets.only(bottom: 70),
padding: EdgeInsets.only(left: 30, right: 30),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Material(
type: MaterialType.transparency,
child: Ink(
decoration: BoxDecoration(
border:
Border.all(color: Color(0xFF57D0F4), width: 2.0),
color: Colors.transparent,
shape: BoxShape.circle,
),
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddProduct()),
);
},
child: Padding(
padding: EdgeInsets.all(13.0),
child: Icon(
Icons.add,
size: 55.0,
color: Color(0xFF57D0F4),
),
),
),
),
),
Material(
type: MaterialType.transparency,
child: Ink(
decoration: BoxDecoration(
border:
Border.all(color: Color(0xFF57D0F4), width: 2.0),
color: Colors.transparent,
shape: BoxShape.circle,
),
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => RemoveProduct()),
);
},
child: Padding(
padding: EdgeInsets.all(13.0),
child: Icon(
Icons.delete_outline,
size: 55.0,
color: Color(0xFF57D0F4),
),
),
),
),
),
Material(
type: MaterialType.transparency,
child: Ink(
decoration: BoxDecoration(
border:
Border.all(color: Color(0xFF57D0F4), width: 2.0),
color: Colors.transparent,
shape: BoxShape.circle,
),
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Notify()),
);
},
child: Padding(
padding: EdgeInsets.all(13.0),
child: Icon(
Icons.notifications_none,
size: 55.0,
color: Color(0xFF57D0F4),
),
),
),
),
),
],
),
)
],
),
));
}
}
class LoadingPage extends StatefulWidget {
#override
_LoadingPageState createState() => _LoadingPageState();
}
class _LoadingPageState extends State<LoadingPage> {
List prd;
ScrollController _scrollController = ScrollController();
int _currentMax = 10;
#override
void initState() {
super.initState();
prd = List.generate(10, (i) => "Product ${i + 1}");
_scrollController.addListener(() {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent) {
_getMoreData();
}
});
}
_getMoreData() {
for (int i = _currentMax; i < _currentMax + 10; i++) {
return prd.add("Product ${i + 1}");
}
_currentMax = _currentMax + 10;
setState(() {});
}
#override
Widget build(BuildContext context) {
return ListView.builder(
controller: _scrollController,
itemCount: prd.length + 1,
itemExtent: 70,
itemBuilder: (context, i) {
if (i == prd.length) {
return CupertinoActivityIndicator();
}
return ListTile(
title: AutoSizeText(prd[i]),
);
});
}
}
Thanks for your help #Mobina and #JohnJoe.
I wrapped the ListView.builder with Flexible which fixed the problem and added COntainer to put it inside a greyish background.
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(top: 10.0, bottom: 10.0),
height: 450,
width: 350,
decoration: BoxDecoration(
color: Color(0xFF707070),
borderRadius: BorderRadius.all(
Radius.circular(
10.0,
),
)),
child: Flexible(
child: ListView.builder(
controller: _scrollController,
itemCount: prd.length + 1,
itemExtent: 42.5,
itemBuilder: (context, i) {
if (i == prd.length) {
return CupertinoActivityIndicator();
}
return ListTile(
title: AutoSizeText(prd[i]),
);
}),
),
);
}

How to edit a selected item from a list in flutter

I have been trying to add an edit function to my to do list in which a user can select the item the user wants to edit, then that should pop a dialog where there is a textfield to enter the new value of the selected item and a Button that saves the changes. Currently I have a function that calls the array where the tasks are stored then it is supposed to triger the selected item using index so that at the end that selected value could be given a new value when onPressed, see this edit functionality as instagrams one except it edits text.
The problem comes when calling that function into the dialog's edit button because I am doing it like this onPressed: () => _editToDoItem(_controller.text, index) and since I have to pass 2 parameters there, the error I am getting is Undefined name 'index'. How can this problem be solved to make this edit function work?. By the way, I haven't get to try the edit function because of this error so please correct me if the function or any part of the code is incorrect.
everything to do with the edit function below.
List<ToDoElement> _toDoItems = [];
TextEditingController _controller = TextEditingController();
// this function adds a task to the list
void _addToDoItem(String task) {
if(task.isNotEmpty) {
setState(() {
_toDoItems.add(ToDoElement(task, DateTime.now()));
});
}
}
// this is the function that is supposed to edit the selected index from the _toDoItems array
void _editToDoItem(String newText, int index) {
setState(() {
_toDoItems[index].task = newText;
});
}
_editDialog(BuildContext context) {
return showDialog(context: context, builder: (context) {
return Dialog(
child: Container(
height: 180,
width: 100,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 60,
child: TextField(
controller: _controller,
autofocus: true,
style: TextStyle(fontSize: 18,),
)
),
Container(
height: 65,
width: double.infinity,
margin: EdgeInsets.only(top: 5,),
child: RaisedButton(
textColor: Colors.white,
color: Colors.red,
child: Text('EDIT'),
onPressed: () {
_editToDoItem(_controller.text, index); // error on index, Undefined name 'index'
FocusScope.of(context).requestFocus(FocusNode());
},
),
),
],
),
),
);
});
}
full main.dart file
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();
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) {
return showDialog(context: context, builder: (context) {
return Dialog(
backgroundColor: Colors.transparent,
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: _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),
),
),
)
),
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(_controller.text, index);
FocusScope.of(context).requestFocus(FocusNode());
},
),
),
],
),
),
);
});
}
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),
),
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 can copy paste run full code below
You can provide index to _editDialog then _editToDoItem can get index
code snippet
_editDialog(BuildContext context, int index)
...
FlatButton(
child: Text(
'Edit',
style: TextStyle(color: Colors.red, fontSize: 16.5),
),
onPressed: () => _editDialog(context, index),
),
working demo
full code
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 _controller1 = 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,
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: _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),
),
),
)),
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(_controller.text, index);
FocusScope.of(context).requestFocus(FocusNode());
},
),
),
],
),
),
);
});
}
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: _controller1,
autofocus: true,
onSubmitted: (val) {
_addToDoItem(val);
_controller1.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(_controller1.text);
_controller1.clear();
FocusScope.of(context).requestFocus(FocusNode());
},
),
),
),
],
),
),
_buildToDoList()
]),
),
);
}
}