I am building a settings page.
class SettingsScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
"Settings",
style: TextStyle(
color: primaryColor,
fontFamily: titleFontStyle
),
),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: primaryColor),
onPressed: () => Navigator.of(context).pop(),
),
centerTitle: true,
backgroundColor: Colors.white,
elevation: 0.0,
),
backgroundColor: Colors.white,
body: Container(
width: double.infinity,
height: MediaQuery.of(context).size.height - 40.0,
padding: EdgeInsets.fromLTRB(20.0, 60.0, 20.0, 0.0),
child: ListView(
children: <Widget>[
Container(
child: TextField(
autofocus: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Username',
),
),
),
Container(
margin: EdgeInsets.only(top: 20.0),
child: RaisedButton(
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 40.0),
textColor: Colors.white,
color: primaryColor,
child: Text(
'Update',
style: TextStyle(
color: Colors.white
),
),
onPressed: () {},
),
),
],
),
),
);
}
}
I get an render flex overflow error whenever I try to press the back button.
The error message is as follows :-
The specific RenderFlex in question is:
I/flutter (18259): RenderFlex#17a8f relayoutBoundary=up1 OVERFLOWING
I/flutter (18259): creator: Column ← MediaQuery ← LayoutId
I have tried wrapping the Containers in SingleChildScrollView() but it doesn't work.
I used to use Column() before using ListView() but that didn't work either.
This is caused by soft keyboard , add this to scaffold widget
resizeToAvoidBottomInset : false
or
resizeToAvoidBottomPadding: false,
it existe different ways to avoid that but more important the only fix that error, that could we done with what C4C said, its understand what happens and you can know more about this error reading about it in this post from Scott Stoll from Flutter Community
You could use also Expanded or Flexible widgets to avoid this, you will understand more about this errors after read the 4 post he did.
Also you can remove the size from the container and add the property shrinkWrap: true, of the listview.
Related
I have an alert popup using rflutter_alert, that contains a text widget (and Ok button). The text is wrapped in a SingleChildScrollView to scroll the text vertically.
This works with no issues when in debug mode - either with the emulator or on my android phone. But the release version after being approved on Google Play, does not work. The text area is one long grey box with no text. Images as follows.
My other rflutter_alerts (without a scrollable view) work fine in release mode.
Is there a user permission required for release for scrolling views? Or some other difference between test and release?
// Alert to display roster message
_onAlertShowRosterNotes(context, String rosterMsg) {
var alertStyle = AlertStyle(
isCloseButton: false,
);
Alert(
context: context,
style: alertStyle,
title: 'Roster Message',
content: Column(
children: <Widget>[
Container(
margin: const EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 0.0),
padding: const EdgeInsets.fromLTRB(6.0, 3.0, 6.0, 3.0),
height: 280.0,
width: 230,
decoration: BoxDecoration(
border: Border.all(
color: kMainColor,
width: 0.5,
),
),
child: Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Text(rosterMsg,
style: TextStyle(
color: kBodyText,
fontWeight: FontWeight.normal,
fontSize: 16.0,
),
),
),
),
),
],
),
buttons: [
DialogButton(
child: Text('OK', style: TextStyle(color: Colors.white, fontSize: 20)),
color: kMainColor,
onPressed: () {
Navigator.pop(context, false);
},
),
],
).show();
}
The problem was caused by the Expanded widget. Once I removed this, the problem went away.
I created a custom rounded AppBar using a code found here, but with just a title in the center.
I wanted to add a backbutton in the top left corner inside AppBar and I tried nesting a button and the text in a Row, but the result is that neither the button or the text are shown. Any help?
Here the code:
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
// ignore: must_be_immutable
class RoundedAppBar extends StatelessWidget implements PreferredSizeWidget {
String title;
RoundedAppBar(this.title);
#override
Widget build(BuildContext context) {
return PreferredSize(
child: LayoutBuilder(builder: (context, constraints) {
final width =
constraints.maxWidth * 16; //per modificare "rotondità" app Bar
return OverflowBox(
maxHeight: double.infinity,
maxWidth: double.infinity,
child: SizedBox(
height: width,
width: width,
child: Padding(
padding: EdgeInsets.only(
bottom: width / 2 - preferredSize.height / 2),
child: Container(
alignment: Alignment.bottomCenter,
padding: EdgeInsets.only(bottom: 10),
decoration: BoxDecoration(
color: const Color(0xff000350),
shape: BoxShape.circle,
),
child: Row(
children: [
Align(
alignment: Alignment.centerLeft,
child: IconButton(
color: Colors.black,
icon: Icon(Icons.chevron_left),
onPressed: () => Navigator.pop(context),
),
),
Text(
title,
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'Conformity',
color: Colors.white,
fontSize: 30,
fontWeight: FontWeight.normal),
),
],
)),
),
),
);
}),
preferredSize: preferredSize);
}
#override
Size get preferredSize => Size.fromHeight(80);
EDIT:
Tried using ListTile as suggested, something happened but didn't work properly.
Here the result.
child: ListTile(
title: Text(
title,
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'Conformity',
color: Colors.white,
fontSize: 30,
fontWeight: FontWeight.normal),
),
leading: IconButton(
color: Colors.white,
icon: Icon(Icons.chevron_left),
onPressed: () => Navigator.pop(context),
),
),
EDIT:
I inserted your code as shown. With trial and error, using 35 as height I was able to see the title, but still no button.
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
_buildBack(true, context),
Container(
height: 35,
child: Text(
title,
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: 'Conformity',
color: Colors.white,
fontSize: 30,
fontWeight: FontWeight.normal),
),
),
_buildBack(false, context),
],
and
Widget _buildBack(bool isPlaceHolder, BuildContext context) {
return Visibility(
child: InkWell(
child: Icon(
Icons.close,
size: 35,
),
onTap: () => Navigator.of(context, rootNavigator: true).pop('dialog'),
),
maintainSize: true,
maintainAnimation: true,
maintainState: true,
visible: !isPlaceHolder,
);
}
and here the result
You can use a ListTile and use a IconButton as leading.
ListTile(
leading: IconButton(
icon: Icon(Icons.back),
title: '',
onPressed => Navigator.pop(context),
),
),
Another possibility I see:
As the child from the AppBar
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
_buildBack(true, context),
Container(
height: height,
child: Text(
'$_title',
style: Theme.of(context).textTheme.headline2,
),
),
_buildBack(false, context),
],
),
In another place outside the builder.
Widget _buildBack(bool isPlaceHolder, Buildcontext context) {
return Visibility(
child: InkWell(
child: Icon(
Icons.close,
size: widget.height,
),
onTap: () => Navigator.of(context, rootNavigator: true).pop('dialog'),
),
maintainSize: true,
maintainAnimation: true,
maintainState: true,
visible: !isPlaceHolder,
);
}}
Here there is again a row as you have tried it yourself, but this one is set up a little differently and an iconButton is built before and after the text, but so that the text remains in the center, the second one is made invisible,
I need to make a popup menu kind of button.
Is there any way to make a pop up menu floating action button,this is my desired view
You can use flutter speed dial package.
Visit - https://pub.dev/packages/flutter_speed_dial .
And here is a youtube video - https://www.youtube.com/watch?v=1FmATI4rOBc
Your answer is PopupMenuItem class, which will help you get the desirable result.
PLEASE NOTE: I have just demonstrated how to use, and with what code, you achieve the result. You can anyways, play with it, and get your desirable result.
CODE SNIPPET FOR CREATING A POPUP MENU ITEM
PopupMenuButton<Choice>(
itemBuilder: (context) => [
PopupMenuItem()
],
icon: Icon(),
offset: Offset()
)
CODE FOR REFERENCE
class _MyHomePageState extends State<MyHomePage> {
Widget _offsetPopup() => PopupMenuButton<int>(
itemBuilder: (context) => [
PopupMenuItem(
value: 1,
child: Text(
"Flutter Open",
style: TextStyle(
color: Colors.black, fontWeight: FontWeight.w700),
),
),
PopupMenuItem(
value: 2,
child: Text(
"Flutter Tutorial",
style: TextStyle(
color: Colors.black, fontWeight: FontWeight.w700),
),
),
],
icon: Container(
height: double.infinity,
width: double.infinity,
decoration: ShapeDecoration(
color: Colors.blue,
shape: StadiumBorder(
side: BorderSide(color: Colors.white, width: 2),
)
),
//child: Icon(Icons.menu, color: Colors.white), <-- You can give your icon here
)
);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
padding: EdgeInsets.only(right: 10.0, bottom: 10.0),
child: Align(
alignment: Alignment.bottomRight,
child: Container(
height: 80.0,
width: 80.0,
child: _offsetPopup()
)
)
)
);
}
}
The above will give you this result:
PRO-TIP
You can play around with Offset() to decide the position of your PopupMenuItems
I'm trying to implement a button that calls another page when it is tapped.
I'm wrapping a container with the inkWell widget that has a splash color effect and the onTap (){}.
The button shows the splash color effect with the onTap (){} empty however when I add a Navigator.push.. to call another page, the splash color effect disappears.
Any idea about how to solve this?
This is the code
Padding(
padding: const EdgeInsets.only(top: 11),
child: Material(
color: Colors.white,
child: InkWell(
splashColor: Colors.grey,
onTap: () {
Navigator.push(
context,
PageTransition(
type: PageTransitionType.downToUp,
duration: Duration(milliseconds: 200),
child: ProfileProduct(
imageUrl: widget.reviews.imageUrl,
cost: widget.reviews.cost,
name: widget.reviews.userName,
address: widget.reviews.address,
brand: widget.reviews.brand,
productName: widget.reviews.productName,
userImage: widget.reviews.userImage,
currentUserId: widget.reviews.authorId,
cSrateStars: widget.reviews.cSrateStars,
easyPurchaseRateStars:
widget.reviews.easyPurchaseRateStars,
envioDiasRateStars: widget.reviews.envioDiasRateStars,
totalRate: widget.reviews.totalRate,
recomendation: widget.reviews.recomendation,
businessName: widget.reviews.businessName,
fecha: widget.reviews.timestamp,
videoLink: widget.reviews.videoLink,
),
),
);
},
child: Container(
// margin: EdgeInsets.only(top: 10),
height: 280,
width: 190,
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 10, top: 2),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
CircleAvatar(
radius: 12.0,
backgroundColor: Colors.grey,
backgroundImage: widget
.reviews.userImage.isEmpty
? AssetImage(
'assets/images/user_placeholder.jpg')
: CachedNetworkImageProvider(
widget.reviews.userImage),
),
SizedBox(width: 0.0),
Text(
widget.reviews.userName,
style: TextStyle(
fontSize: 15, fontWeight: FontWeight.w700),
),
IconButton(
// alignment: Alignment.topLeft,
icon: _isLiked
? Icon(
Icons.favorite,
color: Colors.red,
)
: Icon(Icons.favorite_border),
iconSize: 15.0,
onPressed: _likePost,
),
],
),
),
AutoSizeText(
widget.reviews.productName,
maxLines: 4,
style: TextStyle(color: Colors.blue, fontSize: 20),
),
SizedBox(height: 3.0),
RatingStars(widget: widget),
SizedBox(height: 8.0),
AutoSizeText(
'$costos',
maxLines: 4,
style: TextStyle(color: Colors.grey),
),
SizedBox(height: 3.0),
Padding(
padding: const EdgeInsets.only(left: 15, right: 15),
child: AutoSizeText(
widget.reviews.comments,
maxLines: 3,
style: TextStyle(color: Colors.grey),
),
),
// SizedBox(height: 3.0),
AutoSizeText(
'See More...',
maxLines: 4,
style: TextStyle(color: Colors.blue),
),
Text(
'${_likeCount.toString()} likes',
style: TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
),
),
I was in the same problem and realised the "NewPage()" loads before the Inkwell splash is shown. I did a small hack by delaying the Navigator.push by 300 milliseconds. It seems to work.
InkWell(
splashColor: Colors.grey,
onTap: () {
Future.delayed(const Duration(milliseconds: 300), () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => NextPage()));
});
},
child:Somewidget,
)
The InkWell widget must have a Material widget as an ancestor. The Material widget is where the ink reactions are actually painted. This matches the material design premise wherein the Material is what is actually reacting to touches by spreading ink.
The ink splashes aren't visible!
If there is an opaque graphic, e.g. painted using a Container, Image, or DecoratedBox, between the Material widget and the InkWell widget, then the splash won't be visible because it will be under the opaque graphic. This is because ink splashes draw on the underlying Material itself, as if the ink was spreading inside the material.
The Ink widget can be used as a replacement for Image, Container, or DecoratedBox to ensure that the image or decoration also paints in the Material itself, below the ink.
editing you widget as per description above
Material(
child: InkWell(
onTap: () {
print("tapped me");
},
splashColor: Colors.grey,....
You must have an onTap: in the inkwell else the splash will not appear even after wrapping it with material
I am new to flutter and trying to make a list of dropdown where upon click the element smoothly toggle showing the inner list of the element.
Please ref the image attached for better understanding.
Following is my staring code.
import 'package:flutter/material.dart';
import 'package:lpa_exam/src/api/api_manager.dart';
class Practicetest extends StatefulWidget {
final examId;
Practicetest({Key key, this.examId});
#override
_PracticetestComp createState() => _PracticetestComp();
}
class _PracticetestComp extends State<Practicetest> {
List listofpracticetest;
void initState() {
super.initState();
APIManager.getpracticetestlist(widget.examId).then((resultpracticelist) {
setpracticetest(resultpracticelist);
});
}
void setpracticetest(value) {
setState(() {
listofpracticetest = value;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xffF8FDF7),
appBar: AppBar(
backgroundColor: Color(0xffF8FDF7), // status bar color
brightness: Brightness.light,
elevation: 0.0,
leading: Container(
margin: EdgeInsets.only(left: 17),
child: RawMaterialButton(
onPressed: () {
Navigator.pushNamed(context, '/');
},
child: new Icon(
Icons.keyboard_backspace,
color: Colors.red[900],
size: 25.0,
),
shape: new CircleBorder(),
elevation: 4.0,
fillColor: Colors.white,
padding: const EdgeInsets.all(5.0),
),
),
),
body: Container(
// height: 200,
margin: EdgeInsets.only(top: 40, left: 30, right: 30),
child: ListView(
shrinkWrap: true,
scrollDirection: Axis.vertical,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
ListTile(
dense: true,
contentPadding: EdgeInsets.all(0),
title: Text(
'Quick set of',
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 18,
),
),
subtitle: Text(
'Practice Tests',
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 22,
color: Colors.black),
)),
Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.grey[300],
width: 1.0,
),
)),
margin: EdgeInsets.only(top: 30),
child: Container(
child: ListTile(
contentPadding: EdgeInsets.all(0),
leading: Text(
'Alegbra',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w500),
),
trailing: Text('1 Submitted ',
style: TextStyle(color: Colors.grey)),
),
)),
],
)
],
),
));
}
}
P.S
So, the list I will be getting from api, currently trying to hard code for mock.
any reference or code will surely help me.
Thanks
Wrap your child under AnimatedContainer it Will do the rest for you and check the official documentation for more info
Found the perfect solution to the requirement of mock.
ExpansionPanelList Widget:
https://api.flutter.dev/flutter/material/ExpansionPanelList-class.html
Render like this: