A RenderFlex overflowed by 21 pixels on the bottom - flutter

I'm newbie in the flutter and I try use Grid View but it shows a render flex overflowed by 21 pixels on the bottom. In the GridView I'm using picture, but it shows error. Anyone know how to fix it? Thank you
I search on the internet, it use SingleChildScrollView, but I don't want to use it because it looks weird for the Grid view
Here my code
import 'package:flutter/material.dart';
import 'package:monger_app/page/detail.dart';
class BudgetSettings extends StatefulWidget {
#override
_BudgetSettingsState createState() => _BudgetSettingsState();
}
class _BudgetSettingsState extends State<BudgetSettings> {
List<Container> categorylist = new List();
var character=[
{"name":"Food", "image":"food.png"},
{"name":"Social-Life", "image":"travel.png"},
{"name":"Transportation", "image":"transportation.png"},
{"name":"Beauty", "image":"makeup.png"},
{"name":"Household", "image":"household.png"},
{"name":"Education", "image":"education.png"},
{"name":"Health", "image":"health.png"},
{"name":"Gift", "image":"gift.png"},
{"name":"Other", "image":"other.png"},
];
_makelist() async {
for (var i = 0; i < character.length; i++) {
final newcharacter = character[i];
final String image = newcharacter["image"];
categorylist.add(
new Container(
padding: new EdgeInsets.all(20.0),
child: new Card( child:
new Column(
children: <Widget>[
new Image.asset('assets/$image', fit: BoxFit.cover,),
new Padding(padding: new EdgeInsets.all(5.0),),
new Text(newcharacter['name'], style: new TextStyle(fontSize: 18.0),),
],
),
),
)
);
}
}
#override
void initState() {
_makelist();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Budget Setting'),
),
body: new GridView.count(
crossAxisCount: 2,
children: categorylist,
),
);
}
}
And here my output

A simple solution for your problem is wrapping your image widget inside a Flexible widget, just like this:
Flexible(
child: Image.asset('assets/$image', fit: BoxFit.cover,),
),

Related

RenderFlex overflowed only on screen transition but no visual issues

First, let me start with I am new to Flutter and this is my first app.
I am running into an issue where I am getting the error:
════════ Exception caught by rendering library ═════════════════════════════════
A RenderFlex overflowed by 24 pixels on the bottom.
The relevant error-causing widget was
Column
lib/widgets/home_screen_cta.dart:42
════════════════════════════════════════════════════════════════════════════════
For the 4 buttons on my home screen.
The weird part is the screen looks fine. No yellow and black bars or anything. This only happens when I transition from the login screen to the home screen. If I move around the app, this does not happen. I do notice it on another form once it is submitted (only for the first submission, not for any others). It also looks bad for the first animation but after that it looks fine.
I was wondering if I should just ignore this but it seems like that is a bad idea.
I have tried changing this to use many other options. This includes:
Changed between Expanded and Flexible
Tried using a container/SizedBox instead
Tried to find another solution for the CTA Item but couldn't find anything that would do this look
At this point, I understand it's a overflow issue but there are no indications of an overflow appearing in the app.
I am trying to make the app responsive in nature so I believe I am doing okay for that. This RenderFlex overflow issue is really puzzling. The fact I don't see the yellow/black bars in the app makes me think this is happening during a transition and I wonder if I should be concerned about it?
Is there a way to control these animations? I really do not like them and I feel it's the transition causing the overflow issue... I'm a bit lost on this.
My code:
Home Screen (HomeDashboard):
import 'package:flutter/material.dart';
import '../app/components/app_drawer.dart';
import '../app/components/app_bar.dart';
import '../lang/app_localizations.dart';
import '../widgets/clock_text.dart';
import '../widgets/home_screen_cta.dart';
import '../widgets/home_screen_dashboard.dart';
import '../widgets/logo_horizontal.dart';
class HomeDashboard extends StatelessWidget {
const HomeDashboard({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: FreshFlowAppBar.get(title: AppLocalizations.of(context)!.title),
drawer: const AppDrawer(),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: const [
Flexible(
flex: 1,
fit: FlexFit.loose,
child: LogoHorizontal(),
),
Flexible(
flex: 1,
fit: FlexFit.loose,
child: ClockText(),
),
Flexible(
flex: 6,
fit: FlexFit.tight,
child: HomeScreenDashboard(),
),
Flexible(
flex: 1,
fit: FlexFit.tight,
child: HomeScreenCta(),
),
],
),
),
),
);
}
}
HomeScreenCta:
import 'package:flutter/material.dart';
import 'package:flutter_font_icons/flutter_font_icons.dart';
import 'package:fresh_flow/services/user.service.dart';
import 'package:provider/provider.dart';
import '../lang/app_localizations.dart';
import '../screens/home/pre_op_entry.dart';
import '../screens/home/prod_entry.dart';
import '../screens/home/post_op_entry.dart';
import '../screens/home/downtime_entry.dart';
import '../services/pre-op.service.dart';
import '../utils/size_helpers.dart';
class HomeScreenCta extends StatefulWidget {
const HomeScreenCta({Key? key}) : super(key: key);
#override
State<HomeScreenCta> createState() => _HomeScreenCtaState();
}
class _HomeScreenCtaState extends State<HomeScreenCta> {
bool _isPreOpSetupCompleted = false;
/// Returns a Widget for the CTA item
Widget _getCtaItem(
BuildContext context,
String title,
IconData iconData,
String routeName,
bool isEnabled,
) {
return GestureDetector(
onTap: () {
if (isEnabled) {
Navigator.of(context).pushNamed(routeName);
}
},
child: Opacity(
opacity: isEnabled ? 1.0 : 0.4,
child: Column( // This is causing RenderFlex overflow issue
children: [
Icon(
iconData,
size: displayHeight(context) * .05,
),
const SizedBox(
height: displayHeight(context) * .03,
),
Text(
title,
style: TextStyle(
fontSize: displayWidth(context) * 0.03,
),
)
],
),
),
);
}
#override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context);
// Define services
final _preOpService = Provider.of<PreOpService>(
context,
listen: false, // No need to listen
);
final _userService = Provider.of<UserService>(
context,
listen: false, // No need to listen
);
_preOpService.init(_userService.getId()!);
// Only Pre-Op Entry is allowed until it is complete all others need to be disabled
if (_preOpService.hasCompletedFirstPreopOfTheDay()) {
setState(() {
_isPreOpSetupCompleted = true;
});
}
final _width =
(displayWidth(context) - MediaQuery.of(context).padding.left) *
0.24;
final _children = [
SizedBox(
width: _width,
child: _getCtaItem(
context,
l10n!.preOpEntry,
FontAwesome.wrench,
PreOpEntry.routeName,
true,
),
),
SizedBox(
width: _width,
child: _getCtaItem(
context,
l10n.prodEntry,
MaterialCommunityIcons.account_hard_hat,
ProdEntry.routeName,
_isPreOpSetupCompleted,
),
),
SizedBox(
width: _width,
child: _getCtaItem(
context,
l10n.postOpEntry,
Icons.task_alt,
PostOpEntry.routeName,
_isPreOpSetupCompleted,
),
),
SizedBox(
width: _width,
child: _getCtaItem(
context,
l10n.downtimeEntry,
Icons.flag_sharp,
DowntimeEntry.routeName,
_isPreOpSetupCompleted,
),
),
];
return Center(
child: Row(
// mainAxisAlignment: MainAxisAlignment.center,
children: _children,
),
);
}
}

Design Rows in Flutter

Hi I'm learning Flutter,
below is the design which I'm trying to achieve,
Could I get the code snippet for first row, so that basing on that I'll try to create remaining here is github https://github.com/phanivaranasi/blood_donar.git pages/dashboard.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:red_cross_hyd/components/header.dart';
import 'package:red_cross_hyd/pages/login.dart';
class DashboardPage extends StatefulWidget {
#override
DashboardPageState createState() => DashboardPageState();
}
class DashboardPageState extends State<DashboardPage> {
#override
Widget build(BuildContext context) {
final content = Scaffold(
appBar: header,
body: SingleChildScrollView(
child: new Stack(
children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
height: 120,
width: double.maxFinite,
child: Stack(
children: <Widget>[
],
)
),
],
)));
return content;
//return new WillPopScope(child: content, onWillPop: () async => false);
}
}
Icons CC: [Flat Icons](https://www.flaticon.com/]
I request you to please update your question, with the issue you are facing. Flutter provides multiple widgets that can help with the layout shown above. The GridView Widget seems to be a perfect fit for the UI shown above.

Using BackdropFilter affects other widgets in a Row Widget - Flutter Web

I am having an issue when trying to blur a container in a Row widget when the user hovers over it (on Chrome). I have a custom widget called PanelLink, which is supposed to shrink in size and blur the background when the cursor goes over it. It works, but for some reason when hovering over one it also blurs every widget to the left not just itself.
FrontPage.dart:
import 'package:flutter/material.dart';
import 'package:website_v2/CustomWidgets/PanelLink.dart';
class FrontPage extends StatefulWidget {
FrontPage();
#override
_FrontPageState createState() => _FrontPageState();
}
class _FrontPageState extends State<FrontPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Website'),
centerTitle: false,
backgroundColor: Colors.blue[900],
),
backgroundColor: Colors.blueGrey[900],
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
PanelLink(false, 'assets/education.jpg'),
PanelLink(true, 'assets/about.jpeg'),
PanelLink(false, 'assets/projects2.jpg'),
],
),
),
);
}
}
PanelLink.dart:
import 'package:flutter/material.dart';
import 'dart:ui';
class PanelLink extends StatefulWidget {
PanelLink(this._blur, this.imageLoc);
final bool _blur;
final String imageLoc;
#override
PanelLinkState createState() => PanelLinkState(_blur, imageLoc);
}
class PanelLinkState extends State<PanelLink> {
PanelLinkState(this._blur, this.imageLoc);
bool isHovering = false;
bool _blur;
String imageLoc;
Widget build(BuildContext context) {
return Expanded(
child: InkWell(
onTap: () => null,
onHover: (hovering) {
setState(() => {isHovering = hovering});
},
child: Stack(children: [
AnimatedContainer(
duration: const Duration(milliseconds: 1000),
curve: Curves.ease,
margin: EdgeInsets.all(isHovering ? 20 : 0),
decoration: BoxDecoration(
color: Colors.black,
image: DecorationImage(
image: AssetImage(imageLoc), fit: BoxFit.cover)),
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: isHovering ? 5 : 0, sigmaY: isHovering ? 5 : 0),
child: Container(
color: Colors.black.withOpacity(0.1),
)),
),
Text('Test')
]),
));
}
}
Here is a picture of the issue occurring. I am hovering the mouse over panel 2, but both panel 1 and 2 are blurred but not panel 3. If I hover over panel 1 only panel 1 is blurred. If I hover over panel 3, all of them are blurred.
I experimented by only making panel two have the BackdropFilter Widget, but panel 1 still got blurred when hovering over panel 2.
Since your using AnimatedContainer widget the problem might be it cant identify the difference between his child widget. Try adding a key value identifier
AnimatedContainer(
child: Container(
key: ValueKey("imageA"), //make sure that this is different on every widget, its better to passed some value here thats different on the other refactored widget
Try experimenting it might work for you
),
),

Flutter snackbar alternative or easier method than wrapping everything in Scaffold?

I'm working on my first Flutter app (debugging on my Android phone). I have a list with row items. When you long-press the row, it copies the content into the user's clipboard. This is working great!
But I need to let the user know that the content was copied.
I've attempted to follow many tutorials on trying to get the row surrounded by a build method or inside a Scaffold, but I can't get any to work. Is there an alternative method to notifying the user (simply) that something like "Copied!" took place?
Notice the commented out Scaffold.of(... below. It just seems like there must be an easier method to notifying the user other than wrapping everything in a Scaffold. (and when I try, it breaks my layout).
import 'package:flutter/material.dart';
import 'package:my_app/Theme.dart' as MyTheme;
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/services.dart';
class RowRule extends StatelessWidget {
final DocumentSnapshot ruleGroup;
RowRule(this.ruleGroup);
_buildChildren() {
var builder = <Widget>[];
if (!ruleGroup['label'].isEmpty) {
builder.add(new Text(ruleGroup['label'],
style: MyTheme.TextStyles.articleContentLabelTextStyle));
}
if (!ruleGroup['details'].isEmpty) {
builder.add(new Text(ruleGroup['details'],
style: MyTheme.TextStyles.articleContentTextStyle));
}
return builder;
}
#override
Widget build(BuildContext context) {
return new GestureDetector(
onLongPress: () {
Clipboard.setData(new ClipboardData(text: ruleGroup['label'] + " " + ruleGroup['details']));
// Scaffold.of(context).showSnackBar(SnackBar
// (content: Text('text copied')));
},
child: Container(
margin: const EdgeInsets.symmetric(vertical: 3.0),
child: new FlatButton(
color: Colors.white,
padding: EdgeInsets.symmetric(horizontal: 0.0),
child: new Stack(
children: <Widget>[
new Container(
margin: const EdgeInsets.symmetric(
vertical: MyTheme.Dimens.ruleGroupListRowMarginVertical),
child: new Container(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 32.0, vertical: 8.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: _buildChildren(),
),
)),
)
],
),
),
));
}
}
The goal is to have a page like this (see image), which I have, and it works and scrolls...etc, but I cannot get it to work with a Scaffold, and therefore, haven't been able to use the snackbar. Each "Row" (which this file is for) should show a snackbar on longPress.
You can use GlobalKey to make it work the way you want it.
Since I don't have access to your database stuff, this is how I gave you an idea to do it. Copy and paste this code in your class and make changes accordingly. I also believe there is something wrong in your RowRule class, can you just copy the full code I have given you and run?
void main() => runApp(MaterialApp(home: HomePage()));
class HomePage extends StatelessWidget {
final GlobalKey<ScaffoldState> _key = GlobalKey();
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xFFFFFFFF).withOpacity(0.9),
key: _key,
body: Column(
children: <Widget>[
Container(
color: Color.fromRGBO(52, 56, 245, 1),
height: 150,
alignment: Alignment.center,
child: Container(width: 56, padding: EdgeInsets.only(top: 12), decoration: BoxDecoration(shape: BoxShape.circle, color: Colors.yellow)),
),
Expanded(
child: ListView.builder(
padding: EdgeInsets.zero,
itemCount: 120,
itemBuilder: (context, index) {
return Container(
color: Colors.white,
margin: const EdgeInsets.all(4),
child: ListTile(
title: Text("Row #$index"),
onLongPress: () => _key.currentState
..removeCurrentSnackBar()
..showSnackBar(SnackBar(content: Text("Copied \"Row #$index\""))),
),
);
},
),
),
],
),
);
}
}
These is a simple plugin replacement for the Snackbar named "Flushbar".
You can get the plugin here - https://pub.dartlang.org/packages/flushbar
You don't have to take care of any wrapping of widgets into scaffold also you get a lot of modifications for you like background gradient, adding forms and so on into Snackbar's and all.
Inside your onLongPressed in GestureDetectore you can do this.
onLongPressed:(){
Clipboard.setData(new ClipboardData(text: ruleGroup['label'] + " " + ruleGroup['details']));
Flushbar(
message: "Copied !!",
duration: Duration(seconds: 3),
)..show(context);
}
This will display the snackbar in you app where you would want to see it also you can get a lot of modification available to you so the you can make it look as per your app.
There are couple of things you need to do, like use onPressed property of the FlatButton it is mandatory to allow clicks, wrap your GestureDetector in a Scaffold. I have further modified the code so that it uses GlobalKey to make things easy for you.
Here is the final code (Your way)
class RowRule extends StatelessWidget {
final GlobalKey<ScaffoldState> globalKey = GlobalKey();
final DocumentSnapshot ruleGroup;
RowRule(this.ruleGroup);
_buildChildren() {
var builder = <Widget>[];
if (!ruleGroup['label'].isEmpty) {
builder.add(new Text(ruleGroup['label'], style: MyTheme.TextStyles.articleContentLabelTextStyle));
}
if (!ruleGroup['details'].isEmpty) {
builder.add(new Text(ruleGroup['details'], style: MyTheme.TextStyles.articleContentTextStyle));
}
return builder;
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: globalKey,
body: GestureDetector(
onLongPress: () {
Clipboard.setData(new ClipboardData(text: ruleGroup['label'] + " " + ruleGroup['details']));
globalKey.currentState
..removeCurrentSnackBar()
..showSnackBar(SnackBar(content: Text('text copied')));
},
child: Container(
margin: const EdgeInsets.symmetric(vertical: 3.0),
child: new FlatButton(
onPressed: () => print("Handle button press here"),
color: Colors.white,
padding: EdgeInsets.symmetric(horizontal: 0.0),
child: new Stack(
children: <Widget>[
new Container(
margin: const EdgeInsets.symmetric(vertical: MyTheme.Dimens.ruleGroupListRowMarginVertical),
child: new Container(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 32.0, vertical: 8.0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: _buildChildren(),
),
),
),
)
],
),
),
),
),
);
}
}
I made a dropdown banner package on pub that allows you to easily notify users of errors or confirmation of success. It's a work in progress as I continue to add visually rich features.
I am not sure if your build() method is completed or you are yet to change it, because it consist of many widgets which are just redundant. Like there is no need to have Container in Container and further Padding along with a FlatButton which would make complete screen clickable. Also having Column won't be a good idea because your screen may overflow if you have more data. Use ListView instead.
So, if you were to take my advice, use this simple code that should provide you what you are really looking for. (See the build() method is of just 5 lines.
class RowRule extends StatelessWidget {
final GlobalKey<ScaffoldState> globalKey = GlobalKey();
final DocumentSnapshot ruleGroup;
RowRule(this.ruleGroup);
_buildChildren() {
var builder = <Widget>[];
if (!ruleGroup['label'].isEmpty) {
builder.add(
ListTile(
title: Text(ruleGroup['label'], style: MyTheme.TextStyles.articleContentLabelTextStyle),
onLongPress: () {
globalKey.currentState
..removeCurrentSnackBar()
..showSnackBar(SnackBar(content: Text("Clicked")));
},
),
);
}
if (!ruleGroup['details'].isEmpty) {
builder.add(
ListTile(
title: Text(ruleGroup['details'], style: MyTheme.TextStyles.articleContentTextStyle),
onLongPress: () {
globalKey.currentState
..removeCurrentSnackBar()
..showSnackBar(SnackBar(content: Text("Clicked")));
},
),
);
}
return builder;
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: globalKey,
body: ListView(children: _buildChildren()),
);
}
}
I read your comments on all answers and here is my conslusion:
You need ScaffoldState object that is just above the widget in tree to show Snackbar. You can either get it through GlobalKey as many have suggested. Fairly simple if the Scaffold is created inside build of the widget, but if it is outside the widget (in your case) then it becomes complicated. You need to pass that key, wherever you need it through Constructor arguments of child widgets.
Scaffold.of(context) is a very neat way to just do that. Just like an InheritedWidget, Scaffold.of(BuildContext context) gives you access of the closest ScaffoldState object above the tree. Else it could be a nightmare to get that instance (by passing it through as constructor arguments) if your tree was very deep.
Sorry, to disappoint but I don't think there is any better or cleaner method than this, if you want to get the ScaffoldState that is not built inside build of that widget. You can call it in any widget that has Scaffold as a parent.

How can i get an image next to a Text?

import 'package:flutter/material.dart';
class PersonalData extends StatelessWidget {
final String Name;
final String Alter;
final String urlImage;
PersonalData(this.Name, this.Alter, this.urlImage);
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(title: new Text(Name),),
body: new Container(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
new Text("Name: " + Name, textAlign: TextAlign.left),
new Text("Alter: " + Alter),
new Image.network(urlImage, height: 200.0, width: 200.0, alignment: Alignment.topRight,),
],
),
),
);
}
}
How can i get the Image near the Text. at the moment the Text stays left and the Image is under the Text on the right
I think your should search fultter docs and library more this is a basic requirement and they have provided it nicely:
Widget _getUserDetailsWidget() {
var assetImage = AssetImage("assets/png/cat.jpg");
var image = new Image(image: assetImage, height: 96.0, width: 96.0, fit: BoxFit.fitWidth,);
final ListTile listTile = new ListTile(title: new Text("Silent Sudo"),
leading: image, subtitle: new Text("Location: India"));
return listTile;
}
Replace new Container() => _getUserDetailsWidget()
Use Row() inside this column .