How do I align the elements of the TabBar in flutter? - user-interface

I have a tab/navigation bar with three options. The icons in it however are not aligned in the middle. The icons look aligned on other devices but not on iPhones. They appear to be pushed a little upwards for some reason.
Widget _bottomNavigationBar(int selectedIndex) =>
Container(
height: 90,
decoration: BoxDecoration(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(52.0),
topRight: Radius.circular(52.0)),
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.black.withOpacity(0.5),
offset: Offset(-5, 5),
blurRadius: 20,
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(52.0),
topRight: Radius.circular(52.0)),
child: BottomNavigationBar(
selectedItemColor: Color(0xFFFE524B),
unselectedItemColor: Color(0xFFFF8C3B),
onTap: (int index) => setState(() => _selectedIndex = index),
currentIndex: selectedIndex,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(
Entypo.home,
size: 28,
),
title: Text('')),
BottomNavigationBarItem(
icon: Icon(
Entypo.game_controller,
size: 28,
),
title: Text('')),
BottomNavigationBarItem(
icon: Icon(
Entypo.wallet,
size: 28,
),
title: Text('')),
],
),
));
Thank you for your help!

That is happening because of the 'title' in the bottom nav bar. Basically it is rendering a Text widget with an empty string. Not seen as its empty but its taking the space.
Good thing is that the title property in the BottomNavBar class takes a widget, so, you can pass any widget to it.
I'd suggest passing a Padding widget with zero padding, or maybe a Container with a zero height.
Implementation can look as follows:
BottomNavigationBarItem(
icon: Icon(
Entypo.home,
size: 28,
),
title: Padding(padding: EdgeInsets.all(0.0))),
BottomNavigationBarItem(
icon: Icon(
Entypo.game_controller,
size: 28,
),
title: Padding(padding: EdgeInsets.all(0.0))),
BottomNavigationBarItem(
icon: Icon(
Entypo.wallet,
size: 28,
),
title: Padding(padding: EdgeInsets.all(0.0))),
],
),

Related

Fix multiple image size with same dimension in flutter

my code is inside a ListView Widget. i am having a problem with my images, since each one of them have a dimensions which is different than the other ones. i want them to appear all with the same dimension, but some of them is being bigger than the others.
note : i have used Width and Height and it didn't help
i want both of them to be with the same dimension but the second one is bigger !
i have even tried the BoxFit method as well and didn't help.
here is my code sample:
ListView(
children: List.generate(
sandwichFood.length,
(index) => Padding(
padding: EdgeInsets.all(10),
child: Container(
padding: EdgeInsets.only(left: 10),
decoration: _foodDecor(),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Column(
children: [
Text(
sandwichFood[index],
style: TextStyle(fontSize: 25),
textAlign: TextAlign.left,
),
Text(
'Price : ${sandwichPrice[index]}',
style: TextStyle(fontSize: 20),
),
],
),
Image(
image: AssetImage(sandwichImage[index]),
height: 200,
width: 200,
),
],
),
),
),
),
);
Image class has parameter fit. Try to use it:
Image(
image: AssetImage(sandwichImage[index]),
fit: BoxFit.cover,
height: 200,
width: 200,
)

How to make an Image Icon with a button to change the image like google:

I wanna create, in my Profile Screen, an user's profile photo rounded with a button, or a something creative to change this photo like google:
But what I have now is this:
CircleAvatar(
radius: 75,
backgroundColor: Colors.grey.shade200,
child: CircleAvatar(
radius: 70,
backgroundImage: AssetImage('assets/images/default.png'),
)
),
How can I add a button like in the google example?
Using Stack you can put icon on top of the avatar and at a specific position.
Stack(
children: [
CircleAvatar(
radius: 75,
backgroundColor: Colors.grey.shade200,
child: CircleAvatar(
radius: 70,
backgroundImage: AssetImage('assets/images/default.png'),
),
),
Positioned(
bottom: 1,
right: 1,
child: Container(
child: Padding(
padding: const EdgeInsets.all(2.0),
child: Icon(Icons.add_a_photo, color: Colors.black),
),
decoration: BoxDecoration(
border: Border.all(
width: 3,
color: Colors.white,
),
borderRadius: BorderRadius.all(
Radius.circular(
50,
),
),
color: Colors.white,
boxShadow: [
BoxShadow(
offset: Offset(2, 4),
color: Colors.black.withOpacity(
0.3,
),
blurRadius: 3,
),
]),
),
),
],
)
You can use Stack widget with Positioned as its child widget.

How do I clip the edges of my tab bar container in flutter?

I have a container at the bottom of my screen that has a BottomNavigationBar. I want the container to get the colour of my background. Even after adding CLipRRect it wasn't getting corrected. I also tried to make the container transparent but it showed me an error where I couldn't assign a colour to my container and give it a boxDecoration.I want the excess white part to merge into my background.
//edited
How do I get rid of the shadow from the background?
Widget _bottomNavigationBar(int selectedIndex) => ClipRect(
child: Container(
height: 80,
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(52.0)),
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.grey.withOpacity(0.3),
offset: const Offset(0.0, 0.0),
blurRadius: 52.0),
],
),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(52.0),
topRight: Radius.circular(52.0)),
child: BottomNavigationBar(
selectedItemColor: Color(0xFFFE524B),
unselectedItemColor: Color(0xFFFF8C3B),
onTap: (int index) => setState(() => _selectedIndex = index),
currentIndex: selectedIndex,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(
Entypo.home,
size: 30,
),
title: Text('')),
BottomNavigationBarItem(
icon: Icon(
Entypo.game_controller,
size: 30,
),
title: Text('[![enter image description here][1]][1]')),
BottomNavigationBarItem(
icon: Icon(
Entypo.wallet,
size: 30,
),
title: Text('')),
],
),
)),
);
This is actually not a problem with the bottom navigation bar. You need to set "extendBody" to "true" for the parent Scaffold widget. This will extend the scaffold body content all the way down to the bottom of the screen!
Scaffold(
extendBody: true,
bottomNavigationBar: _bottomNavigationBar(selectedIndex),
);

How do I add a shadow behind the tab bar in flutter?

I want to add a subtle shadow behind this tab bar which is wrapped in a container. I tried to add it but its not showing up evidently.
I had to edit it in this way because I had to crop the edges of the bar to male it rounded.
Widget _bottomNavigationBar(int selectedIndex) => ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(52.0), topRight: Radius.circular(52.0)),
child: Container(
height: 90,
decoration: BoxDecoration(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(82.0),
topRight: Radius.circular(52.0)),
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.black,
offset: Offset(-5, 5),
blurRadius: 10,
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(52.0),
topRight: Radius.circular(52.0)),
child: BottomNavigationBar(
selectedItemColor: Color(0xFFFE524B),
unselectedItemColor: Color(0xFFFF8C3B),
onTap: (int index) => setState(() => _selectedIndex = index),
currentIndex: selectedIndex,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(
Entypo.home,
size: 28,
),
title: Text('')),
BottomNavigationBarItem(
icon: Icon(
Entypo.game_controller,
size: 28,
),
title: Text('')),
BottomNavigationBarItem(
icon: Icon(
Entypo.wallet,
size: 28,
),
title: Text('')),
],
),
)),
);
I want my tab bar to look something like this
here the CLipRRect Widget is cutting your widget in rect with radius.
your box shadow is being cuttoff because of clip r rect
remove clipping widget and then try

Flutter Network Image does not fit in Circular Avatar

I am trying to retrieve bunch of images from an api. I want the images to be displayed in Circular form so I am using CircleAvatar Widget, but I keep getting images in square format.
Here is a screenshot of images
Here is the code I am using
ListTile(leading: CircleAvatar(child: Image.network("${snapshot.data.hitsList[index].previewUrl}",fit: BoxFit.scaleDown,)),),
I tryied using all the properties of BoxFit like cover, contain,fitWidth,fitHeight etc but none of them works.
This Will Work : You need to use backgroundImage:property in order to fit it in Circle.
CircleAvatar(
radius: 30.0,
backgroundImage:
NetworkImage("${snapshot.data.hitsList[index].previewUrl}"),
backgroundColor: Colors.transparent,
)
To Check with Dummy Placeholder:
CircleAvatar(
radius: 30.0,
backgroundImage:
NetworkImage('https://via.placeholder.com/150'),
backgroundColor: Colors.transparent,
)
Had a similar problem in the AppBar actions widget list.
This worked for me:
CircleAvatar(
radius: 18,
child: ClipOval(
child: Image.network(
'image-url',
),
),
),
If you don't want to use CircleAvatar, here is how you can do it.
ClipOval(
child: Image.network(
'https://via.placeholder.com/150',
width: 100,
height: 100,
fit: BoxFit.cover,
),
),
if someone intends to create bordered circular image try this.
Using ClipOval widget is not perfect solution because if images are not square result will be elliptic.
CircleAvatar(radius: (52),
backgroundColor: Colors.white,
child: ClipRRect(
borderRadius:BorderRadius.circular(50),
child: Image.asset("assets/pictures/profile.png"),
)
)
ClipRRect widget prevents image to overflow CircleAvatar widget.
You will need to use NetworkImage, AssetImage, FileImage, MemoryImage or something similar. You can't directly use Image.network, Image.asset or similar due to how Flutter architects its image classes.
An example:
CircleAvatar(
radius: 100.0,
backgroundImage: NetworkImage(...),
)
backgroundImage in CircleAvatar expects to receive an ImageProvider as a parameter. However, Image.network and others don't directly extend the ImageProvider class, they merely extend the StatefulWidget class, even though they use NetworkImage inside. That is why you see in the other answers that ClipOval or ClipRRect is being used. These classes accept a Widget and so they're not as particular as CircleAvatar and similar classes are.
Instead of these workarounds, therefore, for CircleAvatar, you should use NetworkImage and similar classes and for widgets that expect just a Widget, you can use Image.network and similar.
Another reason not to use clips is that they can be more expensive than changing the border radii directly: https://flutter.dev/docs/perf/rendering/best-practices
simply use backgroundImage inside CircleAvatar
CircleAvatar(
backgroundImage: AssetImage("assets/images/dia.jpg",),
),
CircleAvatar(
radius: 26,
backgroundColor: Colors.white,
child: ClipOval(
child: _bytesImage == null
? new Text('No image value.')
: Image.memory(
_bytesImage,
width: 60,
height: 60,
fit: BoxFit.cover,
),
),
),
If anyone is trying to fit a circular image in app bar actions. Try below solution it should work.
Padding(
padding: const EdgeInsets.all(8.0),
child: AspectRatio(
aspectRatio: 1,
child: CircleAvatar(
backgroundImage: NetworkImage('https://picsum.photos/seed/picsum/200/500'),
),
),
)
AspectRatio first tries the largest width permitted by the layout constraints(here the appbar). If I remove the padding image radius will be of appbar size. So add padding to control the size of circular image.
this work for me
CircleAvatar(
child: ClipRRect(
borderRadius: new BorderRadius.circular(100.0),
child:Image.network("http://www.rd.com/wp-content/uploads/2017/09/01-shutterstock_476340928-Irina-Bg-1024x683.jpg"),
),),
Wrap your CircleAvatar widget under Stack widget.
return Stack(
children: [
CircleAvatar(
radius: 50.0,
backgroundImage: NetworkImage(
'https://i.pinimg.com/474x/0c/eb/c3/0cebc3e2a01fe5abcff9f68e9d2a06e4.jpg'),
),
],
);
Here is a round picture with a shadow:
child: AspectRatio(
aspectRatio: 1/1,
child: Container(
margin: EdgeInsets.all(
10.0
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100.0),
boxShadow:[
BoxShadow(
color: Color.fromARGB(60, 0, 0, 0),
blurRadius: 5.0,
offset: Offset(5.0, 5.0)
)
],
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(user.image)
)
)
)
)
I had the same problem
CircleAvatar(
radius: 30.0,
backgroundImage: NetworkImage(imageURL),
backgroundColor: Colors.transparent,
));
fixed my issue.
ClipOval(
child: Image.asset(
'assets/dummy.jpg',
fit: BoxFit.contain,
matchTextDirection: true,
height: 50,
))
Use combination of width/height, fit and wrap image in ClipOval like below:
CircleAvatar(
child: ClipOval(
child: Image.network(
_photo,
width: 120,
fit: BoxFit.fill
),
),
radius: 50,
),
If you want to show your image covering whole width of circle avatar then you can use it like this way. And if your image didnot load then it will show default person icon.
CircleAvatar(
child: ClipOval(
child: Center(
child: _image == null
? Icon(
Icons.person,
color: Colors.grey.shade700,
size: 100,
)
: Image.file(
_image,
fit: BoxFit.cover,
width: MediaQuery.of(context).size.width,
),
),
),
radius: 50,
backgroundColor: Colors.grey.shade300,
),
I had the same problem. Using clipoval in circle avatar will make it elliptical.
But this fixed this issue.
CircleAvatar(
radius:25.0,
backgroundImage: NetworkImage(
'${image_url}',
),
backgroundColor: Colors.blue,
),
CachedNetworkImage(
placeholder: (context, url) => Center(
child: CircularProgressIndicator(),
),
errorWidget: (context, url, error) =>
new Icon(Icons.error),
imageBuilder: (context, imageProvider) => Container(
width: 60.0,
height: 60.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: imageProvider,
fit: BoxFit.contain))),
fit: BoxFit.contain,
imageUrl:
"${Constants.MEDIA_LINK}${state.review.company.logo}"),
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MyApp7()),
);
},
child: CircleAvatar(
radius: 50,
// backgroundColor: Colors.amber,
child: CircleAvatar(
backgroundColor: Colors.grey[50],
radius: 50,
// child: Image.asset("assets/images/nophotoMale.png")
backgroundImage:
AssetImage("assets/images/nophotoMale.png")),
),
),
],
),
Below worked in my case:
child: new CircleAvatar(
backgroundColor: Colors.white,
child: ClipRect(
child: Image.network(
'url-to-image',
fit: BoxFit.cover,
),
),
)
It took a few tries to figure this one out.. All these answers did not help me. In the end picture that I inserted into the circle avatar was stretched out to the boundaries of the container that was 2 instances above it. Maybe there are are people who, after going through the answers here, still have the problem that I had. I solved the constraint issue with a FittedBox
GestureDetector(
onTap: () => getImage(),
child: Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Colors.orange,
),
//padding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
child: Container(
width: 140,
height: 160,
child: FittedBox(
child: picture(),
)),
),
),
This is the code for the picture() that I use. I think that the container inside the picture() is not necessary anymore, try it yourself :)
Widget picture() {
if (_image == null) {
return CircleAvatar(
radius: 70,
child: Icon(
Icons.person,
size: 150,
color: Colors.grey[900],
));
} else {
return Container(
width: 140,
height: 140,
child: CircleAvatar(
radius: 70,
backgroundImage: FileImage(_image),
),
);
}
in this solution you can resize the image by container and clip image by clip Oval then add shadow to the image by card.
Container(
width: 100,
height: 100,
child: InkWell(
onTap: () {},
child: Card(
elevation: 5,
shape: RoundedRectangleBorder(
side: BorderSide(color: Colors.grey),
borderRadius: const BorderRadius.all(
Radius.circular(45.0),
),
),
child: Container(
child: ClipOval(
child: CachedNetworkImage(
imageUrl: '{image-url}',
imageBuilder: (context, imageProvider) => Container(
decoration: BoxDecoration(
image: DecorationImage(
image: imageProvider,
fit: BoxFit.fill,
),
),
),
placeholder: (context, url) => Container(
height: 5,
width: 5,
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
),
),
errorWidget: (context, url, error) => Icon(Icons.error),
)),
),
),
));
This is work for me. I think that best way
CircleAvatar(
radius: 30,
backgroundColor: Colors.blueGrey.shade100,
child: Container(
clipBehavior: Clip.antiAlias,
decoration: const BoxDecoration(shape:
BoxShape.circle),
child: const CachedNetworkImage(
url: "https://www.yourimage.com",
),
),
)
Came here as I also had the issue with CirclAvatar and AppBar, where the image would stretch in height. Instead of a radius, as I'm not able to provide it with the component I'm using, I just wrapped the image with a colum when used in appbar. This makes the image not stretch in height. This way I can always control size from the outside too
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(height: 40, width: 40, child: ProfileBadge(),),
],
)
Use AvatarView lib https://pub.dev/packages/avatar_view which provides the functionality to show network/asset images in circular/rectangular form.
To use add below dependency
dependencies:
avatar_view: ^1.0.0+3
Example:
AvatarView(
radius: 60,
borderColor: Colors.yellow,
avatarType: AvatarType.CIRCLE,
backgroundColor: Colors.red,
imagePath:
"https://images.pexels.com/photos/415829/pexels-photo-415829.jpeg?cs=srgb&dl=pexels-pixabay-415829.jpg",
placeHolder: Container(
child: Icon(Icons.person, size: 50,),
),
errorWidget: Container(
child: Icon(Icons.error, size: 50,),
),
),
It also provide funtionality to add borders around widget, for more example visit above link
Output:
this worked for me
Transform.scale(
scale: 0.6,
child: ClipOval(
child: Image.network(
<IMAGE URL HERE>,
),
),
)

Resources