CircleAvatar as leading in ListTile - flutter

In my ListTile, I want a CircleAvatar with a border, that's why I have a CircleAvatar inside an other. The problem is the border doesn't appear. And when I try my code outside a ListTile, it works ...
Code:
class TestTile extends StatelessWidget {
const TestTile({super.key});
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(children: const [
/***** DOES NOT WORK *****/
Card(
child: SizedBox(
width: 200,
height: 100,
child: ListTile(
leading: CircleAvatar(
radius: 32,
backgroundColor: Colors.blue,
child: CircleAvatar(
radius: 30,
backgroundColor: Colors.red,
)),
title: Text("test"),
))),
/***** WORKS *****/
CircleAvatar(
radius: 32,
backgroundColor: Colors.blue,
child: CircleAvatar(
radius: 30,
backgroundColor: Colors.red,
))
]));
}
}

It's because a ListTile has a fixed height. The CircleAvatars simply don't fit in them with your wanted radiuses so they both get shrunk down to largest size that does fit. If you try with smaller radiuses, like 20 and 18 for example you will see that it does work.
To increase the height of the ListTile you can also try to set the visualDensity for example like this, then it might fit
child: ListTile(
visualDensity: VisualDensity(vertical: 2),

Instead of putting two CircleAvatar inside each other to get border, use Container with decoration property, like this:
Card(
child: SizedBox(
width: 200,
height: 100,
child: ListTile(
leading: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: Colors.blue, width: 2)),
child: CircleAvatar(
radius: 30,
backgroundColor: Colors.red,
),
),
title: Text("test"),
))),

Related

How to add shadow just to an image in Card in Circle Avatar in flutter?

I am new to flutter and I want to add shadow to an image in Card (shadow just to an image not the text), how can I do that? Below is the snippet of my code, please let me know how can I do that, thank you.
child: Container(
height: 70,
child: Card(
child: ListTile(
onTap: () {},
title: Text(eventList[index].event_name),
leading: CircleAvatar(
backgroundImage: NetworkImage(eventList[index].imageURL),
),
),
),
),
you can wrap the CircleAvatar with another Container and specify the boxShadow property in its decoration, or for more accuracy, just use a DecoratedBox like this:
Container(
height: 70,
child: Card(
child: ListTile(
onTap: () {},
title: Text("eventList[index].event_name"),
leading: DecoratedBox(
decoration: BoxDecoration(
boxShadow: <BoxShadow>[
BoxShadow(
color: Colors.black.withOpacity(.2),
blurRadius: 5,
offset: const Offset(0, 10),
)
]),
child: CircleAvatar(
backgroundImage: NetworkImage("eventList[index].imageURL"),
),
),
),
),
);
You can simply use a Widget called PhysicalModel where it can easily show shadows. You can play with the properties such as color and elevation for your desired shadow effect.
https://api.flutter.dev/flutter/widgets/PhysicalModel-class.html
leading: PhysicalModel(
color: Colors.grey.withOpacity(0.8),
shape: BoxShape.circle,
elevation: 10.0,
child: const CircleAvatar(
backgroundImage: NetworkImage(
'https://i1.sndcdn.com/artworks-000486414654-mt7qdt-t500x500.jpg'),
),
),

How to center ElevatedButton in flutter?

I imported [sliding up panel][2] from pub.dev and everything is good except for one issue. I'm looking for a way to center the 'blue circle' vertically. (in between 'red appbar' and 'buttom slider') I tried wraping the code with 'center' or using mainaxisalignment but it doesn't work. Other things I tried which I found on google just gave me an errors. Please help.
Thanks in advance
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(200),
child: AppBar(
backgroundColor: Colors.pinkAccent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(bottom: Radius.circular(100))
),
flexibleSpace: Container(
alignment: Alignment.center,
child: Text(
'Red AppBar',
style: TextStyle(
color: Colors.white,
fontSize: 50.0,
fontWeight: FontWeight.bold
),
),
),
),
),
body: SlidingUpPanel(
renderPanelSheet: false,
panel: _floatingPanel(),
collapsed: _floatingCollapsed(),
body: ElevatedButton(
onPressed: () {},
child: Text('Blue Circle'),
style: ElevatedButton.styleFrom(
shape: CircleBorder(),
padding: EdgeInsets.all(20),
),
)
),
);
Widget _floatingCollapsed() {
return Container(
decoration: BoxDecoration(
color: Colors.blueGrey,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(24.0), topRight: Radius.circular(24.0)),
),
margin: const EdgeInsets.fromLTRB(24.0, 24.0, 24.0, 0.0),
child: Center(
child: Text(
"buttom slider",
style: TextStyle(color: Colors.white),
),
),
);
}
Widget _floatingPanel() {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(24.0)),
boxShadow: [
BoxShadow(
blurRadius: 20.0,
color: Colors.grey,
),
]
),
margin: const EdgeInsets.all(24.0),
child: Center(
child: Text("LEVEL INFO"),
),
);
}
Also, what could be the best way to give margin to the 'blue circle' so it won't touch the far left and far right side of the screen?
The SlidingUpPanel's body is using Stack, also getting full screen size. You can check
#override
Widget build(BuildContext context) {
return Stack(
alignment: widget.slideDirection == SlideDirection.UP
? Alignment.bottomCenter
: Alignment.topCenter,
children: <Widget>[
//make the back widget take up the entire back side
widget.body != null
? AnimatedBuilder(
animation: _ac,
builder: (context, child) {
return Positioned(
top: widget.parallaxEnabled ? _getParallax() : 0.0,
child: child ?? SizedBox(),
);
},
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: widget.body,
),
)
You can play with Align on body and wrapping with SizedBox. You can use LayoutBuilder or MediaQuery to provide size.
body: SlidingUpPanel(
renderPanelSheet: false,
panel: _floatingPanel(),
collapsed: _floatingCollapsed(),
body: Align(
alignment: Alignment(0.0, -.3), //play with it
child: SizedBox(
width: 200,
height: 200,
child: ElevatedButton(
As per the documentation of sliding_up_panel, the body represents the widget that lies underneath the sliding panel and it automatically sizes itself to fill the screen. So it occupies full screen. Since you expanded AppBar to 200 unit, the body Widget was pushed down, hence you are seeing the centre point also pushed down by 200 unit. If you change the body height to occupy full screen from the start, by setting the Scaffold property extendBodyBehindAppBar with true, you will place the widget in the correct centre point.
if you add the below line immediately after the Scaffold. You will get desired result.
return Scaffold(
extendBodyBehindAppBar:true,

Flutter Circular Avatar background color while loading

I used two circular avatar (the first one with a white background just a little bigger to create a white border).
Also the second one have the background property set to white.
However before the image is loaded I see a blue background. As you can see form the code there are no one blu widget on the back...
I wold like to have a black or white background while the widget is loading the picture.
return Scaffold(
backgroundColor: Colors.white,
body: Container(
padding: const EdgeInsets.only(top: 30),
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: appColor,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(
width: 0,
height: 20,
),
const Center(
child: Text(
'WhyBye ',
style: TextStyle(
color: Colors.white,
fontFamily: 'Savor',
fontSize: 40,
),
),
),
const SizedBox(
width: 0,
height: 10,
),
Stack(
//& Stack contenente l'immagine del profilo.
children: [
_image != null
? CircleAvatar(
radius: 100,
backgroundColor: Colors.white,
child: CircleAvatar(
radius: 96,
backgroundImage: MemoryImage(_image!),
))
: CircleAvatar(
radius: 100,
backgroundColor: Colors.white,
child: CircleAvatar(
radius: 96,
backgroundImage: Variables.userPicUrl.isNotEmpty
? NetworkImage(Variables.userPicUrl)
: null,
)),
Positioned(
//& All'interno del precedente Stack, posizionamento dei pulsanti immagine dalla galleria/fotocamera.
bottom: -10,
left: 15,
child: IconButton(
onPressed: () {
selectImage(ImageSource.gallery);
},
icon: const Icon(Icons.photo_library_rounded),
color: Colors.white,
iconSize: 32,
),
),
Positioned(
bottom: -10,
left: 135,
child: IconButton(
onPressed: () {
selectImage(ImageSource.camera);
},
icon: const Icon(Icons.add_a_photo),
color: Colors.white,
iconSize: 32,
),
),
Following the documentation of CircleAvatar:
If a backgroundColor is not specified, the theme's ThemeData.primaryColorLight is used with dark foreground colors, and ThemeData.primaryColorDark with light foreground colors.
I think you're using the default theme (which uses blue as primary color). Try to explicitly define s transparent color to the inner circle so while it's loading you only see the color of the outer circle
I think you need to add
Blockquote
foregroundImage
ImageProvider?
The foreground image of the circle. [...]
you could decide to use a dark image

How to overlap two circles?

Can someone help me get this layout with the first circle over the second?
image
I have this function:
Widget overlapped() {
final overlap = 25;
final items = [
Container(
padding: EdgeInsets.only(right: 2),
decoration: new BoxDecoration(
color: Colors.blue,
shape: BoxShape.circle,
),
child: CircleAvatar(
radius: 22,
backgroundImage: AssetImage('assets/example_logo.png'),
backgroundColor: Colors.black,
),
),
CircleAvatar(
radius: 22,
backgroundColor: Colors.white,
child: ClipOval(
child: Image.network(
"https://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Google_%22G%22_Logo.svg/1200px-Google_%22G%22_Logo.svg.png",
errorBuilder: (context, exception, stackTrace) {
return Container(color: Colors.white);
},
height: 35,
))),
CircleAvatar(
child: Text('+2', style: TextStyle(color: Colors.white)),
backgroundColor: Theme.of(context).canvasColor),
];
List<Widget> stackLayers = List<Widget>.generate(items.length, (index) {
return Container(
padding: EdgeInsets.fromLTRB(index.toDouble() * overlap, 0, 0, 0),
child: items[index],
);
});
return Stack(children: stackLayers);
}
This function whenever I add an item to the array, it adds a widget on the right. But I want the first to be above the second, the second of the third, etc ...
you could use the Stack widget :
Stack(
children:<Widget>:[
Positioned(
right: 130.0,
child:Container(
shape: BoxShape.circle,
)
),
Positioned(
left: 130.0,
child:Container(
shape: BoxShape.circle,
)
),
]
)
Use Stack and Positioned together.
import 'package:flutter/material.dart';
class OverLap extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Overlap'),
),
body: Container(
padding: const EdgeInsets.all(8.0),
width: 500.0,
child: Stack(
children: <Widget>[
//Change according to your icon
Icon(
Icons.flaky,
size: 50.0,
color: Colors.red,
),
Positioned(
left: 20.0,
//Change according to your icon
child: Icon(
Icons.flaky,
size: 50.0,
color: Colors.blue,
),
),
],
),
),
);
}
}

How to display a circle avatar image in flutter?

When using the folloing code I would expect a circle avatar image but getting an oval. I tried different parameters like width and height on the Container but that didn't help.
appBar: AppBar(
backgroundColor: Colors.white,
leading: IconButton(
icon: new Icon(Icons.star_border, color: Colors.black),
onPressed: () => {},
),
actions: <Widget>[
Container(
//height: 25.0,
// width: 25.0,
child: CircleAvatar(
backgroundImage: NetworkImage('https://lh3.googleusercontent.com/a-/AAuE7mChgTiAe-N8ibcM3fB_qvGdl2vQ9jvjYv0iOOjB=s96-c'),
)
/*
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.fill,
image: NetworkImage(
'https://lh3.googleusercontent.com/a-/AAuE7mChgTiAe-N8ibcM3fB_qvGdl2vQ9jvjYv0iOOjB=s96-c')),
),*/
),
],
You are receiving an oval shape because you are using the CircleAvatar widget in Appbar widget which has limited height.
Try adding a parameter radius inside CircleAvatar Widget
it will return the circle shape you want for the image.
try changing radius size value, according to your need.
CircleAvatar(
backgroundImage: NetworkImage('https://lh3.googleusercontent.com/a-/AAuE7mChgTiAe-N8ibcM3fB_qvGdl2vQ9jvjYv0iOOjB=s96-c'),
radius: 15.0
)
I've had this issue in the past and have found that wrapping the AvatarCircle in a container with 58 width fixes the Circle radius ratio issue, making it a proper circle shape. One pixel more or less may fit your liking. Give this a try:
appBar: AppBar(
backgroundColor: Colors.white,
leading: IconButton(
icon: new Icon(Icons.star_border, color: Colors.black),
onPressed: () => {},
),
actions: <Widget>[
Container(
width: 58.0,
child: CircleAvatar(
backgroundImage: NetworkImage('https://lh3.googleusercontent.com/a-/AAuE7mChgTiAe-N8ibcM3fB_qvGdl2vQ9jvjYv0iOOjB=s96-c'),
)
),
],
i use this code and works with every image size...
CircleAvatar(
child: ClipOval(
child: Image.network(items.logo, fit: BoxFit.fill),
),
backgroundColor: Colors.transparent,
radius: 30,
)
Nothing works for me other than wrapping CircleAvatar with padding of 8.0.
Padding(
padding: const EdgeInsets.all(8.0),
child: CircleAvatar(
...
),
)