How to wrap showModalBottomSheet in SafeArea? - Flutter - 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),
),
)
],
)
],
),
),
),
),
);
}
}

Related

Hooks can only be called from the build method of a widget that mix-in `Hooks`

I want to use modal and I want to use MultilineTextField but when I used it, dart thrown error.
Do you know how to solve this problem?
Hooks can only be called from the build method of a widget that mix-in Hooks.
Future modalWithReason(BuildContext context) {
return showModalBottomSheet(
backgroundColor: Colors.transparent,
isScrollControlled: true,
context: context,
builder: (BuildContext context) {
return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
height: 789.sp,
padding: EdgeInsets.symmetric(horizontal: 16.sp),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
),
child: Column(
children: [
Container(
height: 264.h,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 34.h),
Text(
'理由を記述',
style: bodySemiBold(black),
),
SizedBox(height: 20.h),
MultilineTextField(),
],
),
),
],
),
),
),
],
),
),
);
});
}
I want to use this.
class MultilineTextField extends HookWidget {
MultilineTextFieldForReason({super.key});
final myController = useTextEditingController();
#override
Widget build(BuildContext context) {
return TextField(
keyboardType: TextInputType.multiline,
controller: myController,
maxLines: 4,
decoration: InputDecoration(
border: OutlineInputBorder(
borderSide: BorderSide(
width: 1,
color: borderMidEmphasis,
),
)),
);
}
}

Sliver AppBar not collapse when using listviewbuilder

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;
}
}

Navigator operation requested with a context that does not include a Navigator.(Flutter)

Hi I have a scenario where in I enter the username password based on the credentials it will redirect the user to second screen . I am not sure where did I got wrong? but I am getting this error below:
Unhandled Exception: Navigator operation requested with a context that does not include a Navigator.
Here is the code:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'Animation/FadeAnimation.dart';
import 'AuthenticationService.dart';
import 'PatientList.dart';
class HomePage extends StatelessWidget {
final TextEditingController emailController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
gotoPatientList(BuildContext context) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) =>PatientList()),
);
}
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
Provider<AuthenticationService>(
create: (_) => AuthenticationService(FirebaseAuth.instance),
),
StreamProvider(
create: (context) =>
context.read<AuthenticationService>().authStateChanges,
),
],
child:MaterialApp(
home: SingleChildScrollView(
child:RaisedButton(
onPressed: () {
gotoPatientList(context);
context.read<AuthenticationService>().signIn(
email: emailController.text.trim(),
password: passwordController.text.trim(),
);
},
child: Container(
child: Column(
children: <Widget>[
Container(
height: 400,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/loginHeader.png'),
fit: BoxFit.fill)),
child: Stack(
children: <Widget>[],
),
),
Padding(
padding: EdgeInsets.all(30.0),
child: Column(
children: <Widget>[
FadeAnimation(
1.8,
Container(
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color:
Color.fromRGBO(143, 148, 251, .2),
blurRadius: 20.0,
offset: Offset(0, 10))
]),
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.grey[100]))),
child: TextField(
controller: emailController,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Email or Phone number",
hintStyle: TextStyle(
color: Colors.grey[400])),
),
),
Container(
padding: EdgeInsets.all(8.0),
child: TextField(
controller: passwordController,
obscureText: true,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Password",
hintStyle: TextStyle(
color: Colors.grey[400])),
),
)
],
),
)),
SizedBox(
height: 30,
),
FadeAnimation(
2,
Container(
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
gradient: LinearGradient(colors: [
Color.fromRGBO(214, 0, 27, 1),
Color.fromRGBO(214, 0, 27, 1),
])),
child: Center(
child: Text(
"Login",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold),
),
),
)),
SizedBox(
height: 70,
),
FadeAnimation(
1.5,
Text(
"Forgot Password?",
style: TextStyle(
color: Color.fromRGBO(214, 0, 27, 1)),
)),
],
),
)
],
),
),
),
),
),
);
}
}
class AuthenticationWrapper extends StatelessWidget {
#override
Widget build(BuildContext context) {
final firebaseUser = context.watch<User>();
if (firebaseUser != null) {
return HomePage();
}
return PatientList();
}
}
You can wrap the button in builder to get the context of the app:
Builder(
builder: (context) => RaisedButton(
onPressed: () {
gotoPatientList(context);
context.read<AuthenticationService>().signIn(
email: emailController.text.trim(),
password: passwordController.text.trim(),
);
},
...
),
);

No Material Widget found textfield widgets require a material widget ancestor(Flutter)

Hi I am trying to build a login screen in flutter but I am getting below error when opening it.
No material widget found textfield widgets require a material widget ancestor
class HomePage extends StatelessWidget {
final TextEditingController emailController = TextEditingController();
final TextEditingController passwordController = TextEditingController();
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
Provider<AuthenticationService>(
create: (_) => AuthenticationService(FirebaseAuth.instance),
),
StreamProvider(
create: (context) =>
context.read<AuthenticationService>().authStateChanges,
),
],
child:MaterialApp(
home: SingleChildScrollView(
child: Container(
child: Column(
children: <Widget>[
Container(
height: 400,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/loginHeader.png'),
fit: BoxFit.fill)),
child: Stack(
children: <Widget>[],
),
),
Padding(
padding: EdgeInsets.all(30.0),
child: Column(
children: <Widget>[
FadeAnimation(
1.8,
Container(
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color:
Color.fromRGBO(143, 148, 251, .2),
blurRadius: 20.0,
offset: Offset(0, 10))
]),
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.grey[100]))),
child: TextField(
controller: emailController,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Email or Phone number",
hintStyle: TextStyle(
color: Colors.grey[400])),
),
),
Container(
padding: EdgeInsets.all(8.0),
child: TextField(
controller: passwordController,
obscureText: true,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Password",
hintStyle: TextStyle(
color: Colors.grey[400])),
),
)
],
),
)),
SizedBox(
height: 30,
),
RaisedButton(
padding:
EdgeInsets.only(left: 100, right: 100, top: 20, bottom: 20),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(28.0),
side: BorderSide(color: Colors.red)),
onPressed: () {
gotoPatientList(BuildContext context) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) =>PatientList()),
);
}
context.read<AuthenticationService>().signIn(
email: emailController.text.trim(),
password: passwordController.text.trim(),
);
gotoPatientList(context);
},
color: Color.fromRGBO(214, 0, 27,1),
textColor: Colors.white,
child: Text("Login".toUpperCase(),
style: TextStyle(fontSize: 14)),
),
Padding(padding:EdgeInsets.only(top: 15),
),
ClipOval(
child: RaisedButton(
onPressed: () {
gotoForgotPassword(BuildContext context) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) =>ForgotPassword()),
);
}
gotoForgotPassword(context);
},
child: Text("Forgot Password"),
textColor: Colors.white,
color:Color.fromRGBO(214, 0, 27, 1),
),
),
],
),
)
],
),
),
),
),
);
}
}
In material design most widgets are conceptually printed on a sheet of material In flutter material library that material is represented by the Material widget that renders ink splashes
Wrap the SingleChildScrollView in a Builder:
Builder(
builder: (context) => SingleChildScrollView......
This is because the context you are using is not a child of MaterialApp.
A better solution will be to put MaterialApp in a widget MyApp for example, and use HomePage widget as home for the MaterialApp.
Also wrap the SingleChildScrollView inside Scaffold(body: SingleChild....

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.