Image does not load on Flutter Draw Header - flutter

I'm new to flutter-dart and I've been trying to load a image to my draw header, so far unsuccessfully. Can anyone shed some light on it? Please find my code below.
class MainDrawer extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
decoration: BoxDecoration(
//color: Theme.of(context).backgroundColor,
image: DecorationImage(
image: AssetImage('assets/images/title_fb_600.png'),
fit: BoxFit.cover,
)),
child: Text("Some Text"),
//ListTile(
// leading: Icon(Icons.monetization_on),
// title: Text(
// "TRIPLE A",
// style: TextStyle(color: Colors.white, fontSize: 20),
// ),
),
ItemDrawer("Carteira Recomendada", Icons.star, 16),
ItemDrawer("Carteira R\$10", Icons.ten_k, 16),
ItemDrawer("Minha Carteira", Icons.favorite, 16),
ItemDrawer("Notícias", Icons.new_releases, 16),
ItemDrawer("Minha Conta", Icons.account_circle, 16),
ItemDrawer("Configurações", Icons.settings, 16),
],
),
);
}
}
My pubspec.yaml....
> flutter:
>
uses-material-design: true
>
assets:
> - assets/images/title3a_fb_600.png
And folder structure...
folder structure

Your pubspec file looks good. I'm assuming you only want to include this single image as an asset.
Try using this package, and replacing the DrawerHeader class with a ProgressiveImage component here.
https://pub.dev/packages/progressive_image
This package helps you to cache the image, to prevent having to reload it again, and it also adds a blur animation while it loads this asset.
If you need to layer the drawer header (and add other information, such as an avatar icon, or email information), you can add this component into a Stack collection, then make sure that the ProgressiveImage is the first in the Stack
If you also need to set a custom height to the drawer header, then make sure to wrap this Stack with a Container and manually set the height of this element

Related

How to make an Image.asset() to fit a SizedBox() in Row?

Having a card (see image below)
Figma Info card
All I need to do is to reach this UI but look what I've got:
My Info card
As you can see the image is not fitted, however I created a SizedBox with needed width and heigth, child FittedBox, which has its own child Image.asset but it's not fitted.
DevTools say that the SizedBox itself has 100x100(which is to be as expected) but the Image is not:(
So could you guys suggest me any possible solution or idea?
Appreciate any answer:))
I've tried to put it in Expanded but the Column with Text begins to overflow, I've also tried to create a Container() with ImageDecoration but this is not working as well.
This is the image I need to fit (in case someone wants to try)
Here is the code of my InfoCard() widget:
class InfoCard extends StatelessWidget {
final String heading;
final String description;
const InfoCard({super.key, required this.heading, required this.description});
#override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
height: 157.0,
padding: const EdgeInsets.all(20.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
color: ColorConstants.kBackgroundSecondary,
),
child: Row(
children: [
SizedBox(
width: 100.0,
height: 100.0,
child: FittedBox(
child: Image.asset(
'/images/info_card_icon.png',
),
),
),
const SizedBox(width: 20.0),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
heading,
style: Theme.of(context).textTheme.headlineSmall,`
),
const SizedBox(height: 10.0),
Text(
description,
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(color: ColorConstants.kText),
),
],
),
)
],
),
);
}
}
After #CCP suggestion to remove FittedBox and set Image.asset fit = BoxFit.cover DevTools show me 100x100 image size.
WIth FittedBox()
After I removed FIttedBox()
But as you can see even it's 100x100, the image itself is not expanded as I want
It should match the whole purple area I think
I don't think the problem is the code, but the image
I'm not an image expert so I speak as a hypothesis: maybe even the images that contain only the object have a transparent box with a dimension behind it, and in your image that box was big and made your image small. I tried copying the image to a smaller box and using that fixed the size issue.
info_card_icon2
In your image.asset give his property
fit: BoxFit.cover

Creating a custom button from an image with rounded sides in Flutter

I would like to create a custom button from an image in Flutter.
I've created the following image to be used as the background for the button:
As you can see, the sides of the button image have a perfectly rounded half-circle shape.
My requirements for the button are:
The half-circle sides of the button should remain perfectly rounded (i.e. not get stretched).
Only the middle part of the button's image should stretch in order to accommodate its content.
The button can't have a fixed size, and should grow according to its content.
The button's content should overlap with the half circle areas of the button.
Ideally, it should look something like this:
I've created the following button Widget in Flutter:
import 'package:flutter/material.dart';
class MyButton extends StatelessWidget {
final String text;
final double fontSize;
const MyButton({Key? key, required this.text, required this.fontSize})
: super(key: key);
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {},
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/my-button.png'),
fit: BoxFit.fill),
),
child: Padding(
padding: EdgeInsets.all(24),
child: Text(text,
style: TextStyle(fontSize: fontSize, color: Colors.white)),
),
),
);
}
}
Using the Widget above, I've created 4 buttons:
Column(children: [
MyButton(text: 'Play', fontSize: 32.0),
MyButton(text: 'Settings', fontSize: 32.0),
MyButton(text: 'Very very very very very very long text', fontSize: 20.0),
MyButton(text: 'Small', fontSize: 12.0)
])
This resulted in the following buttons:
Now as you can see, the half-circle sides of the buttons are now stretched up/down, and are no longer perfectly rounded.
One of the many things I've tried was playing with the centerSlice attribute of the DecorationImage Widget which looked promising, but the button's sides would stay perfectly rounded only when the button's height was exactly the height of my image (conflicting with requirement #3 listed above).
How can I create a button that meets the requirements I've listed above?
You need to maintain the image width, others fit doesn't looks better imo. Follow this structure, it will provide a little better look
return GestureDetector(
onTap: () {},
child: Container(
padding: EdgeInsets.all(24),
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(24),
image: DecorationImage(
image: AssetImage('assets/images/my-button.png'),
fit: BoxFit.fitWidth,
),
),
child: Text(text,
style: TextStyle(fontSize: fontSize, color: Colors.white)),
),
);

I want to use remaining available space on my page in Flutter

In the screen, I have a Column, it has a cusotm made widget of specific height. Then, I have Expanded, in which I have a TabBar which has three tabs.
In one of those tabs, I want to show a list. First, I have a padding, which contains column. The column has some text, which should remain at top and the list should be shown in the space which is remaining. I am using Expanded for that, but it is not working.
I can't use ListView directly, and also can't use expanded. It is only working when I am giving it a container of fix size. Now, in different screens, it will look different. So, I want to take all of the remaining space and build the list there. Code for reference -
Here is the doubts screen, which is one of the tabs of main screen -
import 'package:flutter/material.dart';
import 'package:my_board_plus/size_config.dart';
import 'package:my_board_plus/styles.dart';
import '../../api_handling/api_fetch/fetch_doubt_questions.dart';
import '../../data_models/doubt_question_model.dart';
class NewDoubtsScreen extends StatefulWidget {
const NewDoubtsScreen({Key? key}) : super(key: key);
#override
State<NewDoubtsScreen> createState() => _NewDoubtsScreenState();
}
class _NewDoubtsScreenState extends State<NewDoubtsScreen> {
late Future<List<DoubtQuestionModel>> doubtQuestionsList;
#override
void initState() {
doubtQuestionsList = fetchDoubtQuestion();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: backgroundColor2,
floatingActionButton: Container(
width: getProportionateScreenWidth(130),
height: getProportionateScreenHeight(50),
decoration: BoxDecoration(
color: brandPurple,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(Radius.circular(20)),
),
child: Center(
child: Text(
'? My Doubts',
style: TextStyle(
color: Colors.white,
fontSize: 15,
),
),
),
),
body: Padding(
padding: EdgeInsets.only(top: 8.0, left: 5),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Trending Doubts',
style: TextStyle(
color: Colors.white,
),
),
Text(
'View all',
style: TextStyle(
color: brandYellow,
decoration: TextDecoration.underline
),
),
],
),
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Container(
height: getProportionateScreenHeight(530),
width: double.infinity,
color: Colors.red,
),
),
],
),
),
);
}
}
The red area that you are seeing is the one. I want it to occupy whole area available in the phone screen, so I can show list in it which should be scrollable. In this case, it is occupying all, but in different screens, it might not. So, please give me some suggestions.
You can try to give the height of the container like
height: double.infinity
Or you can give the height of it with substracting the other height from the screen size like
height: MediaQuery.of(context).size.height - getProportionateScreenHeight(50) //the heigth size that you give the other widget that top of it
try to wrap your Padding widget with the Expanded widget,
Expanded widget in column will take the rest of the space of the screen.
also no need to give height to Container widget, so you can remove getProportionateScreenHeight(530) this one

How do I stop overflow

I am still new to coding, I have created multiple textbutton.icon's but they overflow. How do i stop the overflow. Even if i put is in a row or column it still overflows. I also would like to put more spacing between each row of buttons but that just makes it overflow more. Here is the multiple class code:
class home_buttons {
List<Widget> jeffButtons = [
Button1(),
Button2(),
Button3(),
Button4(),
Button5(),
Button6(),
Button7(),
Button8(),
Button9(),
];
}
Here is the button code:
class Button1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.fromLTRB(0.0, 9.0, 0.0, 0.0),
child: TextButton.icon(
onPressed: () => {},
icon: Column(
children: [
Icon(
Icons.search,
color: Colors.white,
size: 75,
),
Padding(
padding: const EdgeInsets.all(10.0),
child: Text(
'Contact Us',
style: TextStyle(
color: Colors.white,
),
),
),
],
),
label: Text(
'', //'Label',
style: TextStyle(
color: Colors.white,
),
),
),
);
}
}
You can wrap your widgets with the SingleChildScrollView to enable scrolling.
Or if you want to fit the screen inside a Column or Row Widget you can wrap individual widgets with a Flexible Widget
Flutter listview normally have undefined height. The total height of listview is defined based on the items in the list. So when you declare listview directly you get overflow issue.
So as a solution you need to specify the height for the outer container, or use sizedbox to define the height.
Specifying height will solve your issue of overflow. To provide space between buttons you can also wrap that in a container and use the benefit of margin or padding to handle it efficiently.
Please find this code snippet to use Media to find height of device
Container(
height: MediaQuery.of(context).size.height,
color: Colors.white,
child: SingleChildScrollView(
child: Column(
children: [
Here instead of SingleChildScrollView You can use listview or listbuilder which will solve your overflow issue
Hope this helps. Let me know If you want more details. Thanks

How do I remove Flutter IconButton big padding?

I want to have a row of IconButtons, all next to each other, but there seems to be pretty big padding between the actual icon, and the IconButton limits. I've already set the padding on the button to 0.
This is my component, pretty straightforward:
class ActionButtons extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Container(
color: Colors.lightBlue,
margin: const EdgeInsets.all(0.0),
padding: const EdgeInsets.all(0.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
IconButton(
icon: new Icon(ScanrIcons.reg),
alignment: Alignment.center,
padding: new EdgeInsets.all(0.0),
onPressed: () {},
),
IconButton(
icon: new Icon(Icons.volume_up),
alignment: Alignment.center,
padding: new EdgeInsets.all(0.0),
onPressed: () {},
)
],
),
);
}
}
I want to get rid of most of the light blue space, have my icons start earlier on the left, and closer to each other, but I can't find the way to resize the IconButton itself.
I'm almost sure this space is taken by the button itself, 'cause if I change their alignments to centerRight and centerLeft they look like this:
Making the actual icons smaller doesn't help either, the button is still big:
thanks for the help
Simply pass an empty BoxConstrains to the constraints property and a padding of zero.
IconButton(
padding: EdgeInsets.zero,
constraints: BoxConstraints(),
)
You have to pass the empty constrains because, by default, the IconButton widget assumes a minimum size of 48px.
Two ways to workaround this issue.
Still Use IconButton
Wrap the IconButton inside a Container which has a width.
For example:
Container(
padding: const EdgeInsets.all(0.0),
width: 30.0, // you can adjust the width as you need
child: IconButton(
),
),
Use GestureDetector instead of IconButton
You can also use GestureDetector instead of IconButton, recommended by Shyju Madathil.
GestureDetector( onTap: () {}, child: Icon(Icons.volume_up) )
It's not so much that there's a padding there. IconButton is a Material Design widget which follows the spec that tappable objects need to be at least 48px on each side. You can click into the IconButton implementation from any IDEs.
You can also semi-trivially take the icon_button.dart source-code and make your own IconButton that doesn't follow the Material Design specs since the whole file is just composing other widgets and is just 200 lines that are mostly comments.
Wrapping the IconButton in a container simply wont work, instead use ClipRRect and add a material Widget with an Inkwell, just make sure to give the ClipRRect widget enough border Radius 😉.
ClipRRect(
borderRadius: BorderRadius.circular(50),
child : Material(
child : InkWell(
child : Padding(
padding : const EdgeInsets.all(5),
child : Icon(
Icons.favorite_border,
),
),
onTap : () {},
),
),
)
Instead of removing a padding around an IconButton you could simply use an Icon and wrap it with a GestureDetector or InkWell as
GestureDetector(
ontap:(){}
child:Icon(...)
);
Incase you want the ripple/Ink splash effect as the IconButton provides on click wrap it with an InkWell
InkWell(
splashColor: Colors.red,
child:Icon(...)
ontap:(){}
)
though the Ink thrown on the Icon in second approach wont be so accurate as for the IconButton, you may need to do some custom implementation for that.
Here's a solution to get rid of any extra padding, using InkWell in place of IconButton:
Widget backButtonContainer = InkWell(
child: Container(
child: const Icon(
Icons.arrow_upward,
color: Colors.white,
size: 35.0,
),
),
onTap: () {
Navigator.of(_context).pop();
});
I was facing a similar issue trying to render an Icon at the location the user touches the screen. Unfortunately, the Icon class wraps your chosen icon in a SizedBox.
Reading a little of the Icon class source it turns out that each Icon can be treated as text:
Widget iconWidget = RichText(
overflow: TextOverflow.visible,
textDirection: textDirection,
text: TextSpan(
text: String.fromCharCode(icon.codePoint),
style: TextStyle(
inherit: false,
color: iconColor,
fontSize: iconSize,
fontFamily: icon.fontFamily,
package: icon.fontPackage,
),
),
);
So, for instance, if I want to render Icons.details to indicate where my user just pointed, without any margin, I can do something like this:
Widget _pointer = Text(
String.fromCharCode(Icons.details.codePoint),
style: TextStyle(
fontFamily: Icons.details.fontFamily,
package: Icons.details.fontPackage,
fontSize: 24.0,
color: Colors.black
),
);
Dart/Flutter source code is remarkably approachable, I highly recommend digging in a little!
A better solution is to use Transform.scale like this:
Transform.scale(
scale: 0.5, // set your value here
child: IconButton(icon: Icon(Icons.smartphone), onPressed: () {}),
)
You can use ListTile it gives you a default space between text and Icons that would fit your needs
ListTile(
leading: Icon(Icons.add), //Here Is The Icon You Want To Use
title: Text('GFG title',textScaleFactor: 1.5,), //Here Is The Text Also
trailing: Icon(Icons.done),
),
I like the following way:
InkWell(
borderRadius: BorderRadius.circular(50),
onTap: () {},
child: Container(
padding: const EdgeInsets.all(8),
child: const Icon(Icons.favorite, color: Colors.red),
),
),
enter image description here
To show splash effect (ripple), use InkResponse:
InkResponse(
Icon(Icons.volume_up),
onTap: ...,
)
If needed, change icons size or add padding:
InkResponse(
child: Padding(
padding: ...,
child: Icon(Icons.volume_up, size: ...),
),
onTap: ...,
)