Related
I have to create a Card like this:
I had written below code to achieve the desired UI, but it didn't work as expected.
Card(
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(10),
topRight: Radius.circular(10)),
side: BorderSide(width: 5, color: Colors.green)),
child: ListTile(),
)
The code above produced this:
Whereas using the code below:
Card(
elevation: 5,
shape: Border(right: BorderSide(color: Colors.red, width: 5)),
child: ListTile(),
)
generated this output:
How can I create the required UI in flutter?
Use the shape parameter in the Card widget, example:
Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
child: Container() )
I have used ClipPath to achieve the UI asked in the question, check out the below code.
Card(
elevation: 2,
child: ClipPath(
child: Container(
height: 100,
decoration: BoxDecoration(
border: Border(right: BorderSide(color: Colors.green, width: 5))),
),
clipper: ShapeBorderClipper(shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(3))),
),
)
This gives the below output,
If there is a better way to achieve said result kindly do answer.
This solution worked for me. If we remove the shape property from the card, it leaves behind rectangular white corners. No limitation of elevation whatsoever.
Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
shadowColor: Colors.blueAccent,
elevation: 15,
child: ClipPath(
clipper: ShapeBorderClipper(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15))),
child: Container(
height: 180,
decoration: BoxDecoration(
border: Border(
left: BorderSide(color: Colors.red, width: 15)),
color: Colors.yellowAccent.shade100,
),
padding: EdgeInsets.all(20.0),
alignment: Alignment.centerLeft,
child: Container()),
),
)
You should place your Card inside a ClipRRect widget :
return ClipRRect(
borderRadius: BorderRadius.circular(15.0),
child: Card(
elevation: 5,
shape: Border(right: BorderSide(color: Colors.red, width: 5)),
child: ListTile(),
),
);
But I advise you to reduce the value of elevation because it is distorting the small circular borders.
For me, all the solutions using clipping cut off some of the shadow. Anyway, I found an easier solution imo:
Wrap the card's child around a Container widget. Specify the rounded rectangle border for the card, then the colored border side for the container.
Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)),
child: Container(
decoration: BoxDecoration(
border: Border(right: BorderSide(color: Colors.red, width: 8)
),
child: // your card content
)
)
Instead of using a Card you could also use a Container to achieve this, you can use the gradient property on BoxDecoration. The stops property is going to determine the width of your border. Then you can add your colors and have a nice border.
For the rounded edges you can just use the borderRadius property.
Container(
margin: EdgeInsets.symmetric(
horizontal: 4.0,
vertical: 8.0,
),
padding: EdgeInsets.symmetric(
horizontal: 8.0,
vertical: 12.0,
),
child: Text('A "card" with rounded edges and a border'),
decoration: BoxDecoration(
gradient: LinearGradient(
stops: [0.015, 0.015],
colors: [
Colors.blue,
Colors.white,
],
),
borderRadius: BorderRadius.all(
Radius.circular(5.0),
),
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 4.0,
offset: Offset(0.0, 1.5),
),
],
),
)
Result from the code above
You can use the clipBehavior in the Card and move the BorderSide to a Container.
Card(
clipBehavior: Clip.antiAlias,
child: Container(
height: 100,
decoration: BoxDecoration(
border: Border(
right: BorderSide(color: Colors.green, width: 5))),
),
)
I need to add shadows to some icons in my flutter project. I've checked the icon class constructors but nothing points to that. Any idea on how to implement that?
I got what i wanted eventually using this workaround. I hope it helps whoever might need something similar.
Stack(
children: <Widget>[
Positioned(
left: 1.0,
top: 2.0,
child: Icon(icon, color: Colors.black54),
),
Icon(icon, color: Colors.white),
],
),
The Icon widget has a shadows property with which you can give shadows to an icon.
const Icon(
icon,
shadows: <Shadow>[Shadow(color: Colors.black, blurRadius: 15.0)],
size: 60,
color: Colors.white,
)
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: Colors.grey[400],
blurRadius: 5.0,
),
]
),
child: Icon(
Icons.fiber_manual_record,
color: Colors.amber,
size:15,
)
),
You can use IconShadowWidget().
How to use:
1. add dependencies to pubspec.yaml:
icon_shadow: ^1.0.1
2. Import your Dart code :
import 'package:icon_shadow/icon_shadow.dart';
3. add icons:
Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconShadowWidget(
Icon(
Icons.add_circle,
color: Colors.red,
size: 100.0,
),
),
IconShadowWidget(
Icon(
Icons.add_circle,
color: Colors.red,
size: 100.0,
),
shadowColor: Colors.black,
),
IconShadowWidget(
Icon(
Icons.add_circle,
color: Colors.red,
size: 100.0,
),
shadowColor: Colors.black,
showShadow: false,
),
],
),
),
You can also check my GitHub Repository
Whenever you need elevation/shadow, remember the Card widget. So, you can wrap it with Card and SizedBox:
Card(
elevation: 10,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(35.0),
),
child: SizedBox(
width: 35,
height: 35,
child: Icon(
Icons.close,
color: Colors.black,
size: 19,
),
),
)
Even better, here is an icon button with material bubble effect + shadow (in below GIF, shadow's quality looks like bad, it is because of GIF itself)
:
Card(
elevation: 10,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(35.0),
),
child: ClipOval(
child: Material(
color: Colors.transparent, // button color
child: InkWell(
splashColor: Colors.red, // inkwell color
child: SizedBox(
width: 35,
height: 35,
child: Icon(
Icons.close,
color: Colors.black,
size: 19,
),
),
onTap: () {},
),
),
),
)
Took the idea from #Dzeri answer (https://stackoverflow.com/a/55668093/414635) and encapsulated it into a Widget so it became reusable.
Widget
class ShadowIcon extends StatelessWidget {
final IconData icon;
final Color color;
ShadowIcon(this.icon, {Key key, this.color: kLight}) : super(key: key);
#override
Widget build(BuildContext context) {
return Stack(
children: [
Positioned(
left: 0.5,
top: 0.5,
child: BackdropFilter(
filter: ImageFilter.blur(
sigmaX: 1.0,
sigmaY: 1.0,
),
child: FaIcon(this.icon, color: kDark.withOpacity(0.7)),
),
),
FaIcon(this.icon, color: color),
],
);
}
}
The BackdropFilter doesn't seem to be working as expected but anyway all I needed was a subtle drop shadow. I'm also using the package font_awesome_flutter but you can replace the FaIcon by the native Icon widget.
Usage
Your can simply replace the native Icon by the ShadowIcon widget call:
IconButton(
icon: ShadowIcon(FontAwesomeIcons.chevronLeft, color: kLight),
onPressed: () => Get.back(),
),
InkWell(
child: Container(
padding: const EdgeInsets.all(4.0),
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: .5,
),
]),
child: Icon(
Icons.clear,
color: Colors.black,
size: 25,
)),
),
result will be like this pic:
:
Right now, it's not possible to directly add shadows to an Icon widget. You can however use the additional information from your IconData icon to display the icon as a styled text.
Text(
String.fromCharCode(Icons.add.codePoint),
style: TextStyle(
fontFamily: Icons.add.fontFamily,
color: Colors.white,
fontSize: 20.0,
shadows: [
BoxShadow(
color: ColorTheme.blackLight,
spreadRadius: 2,
blurRadius: 2,
)
],
height: 1 //if this isn't set, the shadow will be cut off on the top and bottom
)
);
Try this, use the icon font.
GestureDetector(
child: Container(
padding: EdgeInsets.only(right: 10, top: 10),
child: Text('\u{e5d3}',
style: TextStyle(
fontSize: 22,
color: Colors.white,
fontFamily: 'MaterialIcons',
shadows: [
BoxShadow(color: Colors.black, blurRadius: 2)
])),
),
onTap: () {}
)
Icon data from icons.dart
/// <i class="material-icons md-36">more_horiz</i> — material icon named "more horiz".
static const IconData more_horiz = IconData(0xe5d3, fontFamily: 'MaterialIcons');
You can use decorated icon plugin to do shadow on icon
Code here :
Scaffold(
body: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
DecoratedIcon(
Icons.android,
color: Colors.purple,
size: 60.0,
shadows: [
BoxShadow(
blurRadius: 42.0,
color: Colors.purpleAccent,
),
BoxShadow(
blurRadius: 12.0,
color: Colors.white,
),
],
),
DecoratedIcon(
Icons.favorite,
color: Colors.lightBlue.shade50,
size: 60.0,
shadows: [
BoxShadow(
blurRadius: 12.0,
color: Colors.blue,
),
BoxShadow(
blurRadius: 12.0,
color: Colors.green,
offset: Offset(0, 6.0),
),
],
),
DecoratedIcon(
Icons.fingerprint,
color: Colors.orange,
size: 60.0,
shadows: [
BoxShadow(
color: Colors.black,
offset: Offset(3.0, 3.0),
),
],
),
],
),
),
);
I know this is pretty late, but for anyone looking to add a shadow in circular form should wrap the icon with a CircleAvatar widget and set the backgroundColor proprety of CircleAvatar to Colors.grey.withOpacity (0.5) or to any other color for the shadow. Here's the code snippet
CircleAvatar (
bacgroundColor: Colors.grey.withOpacity (0.5),
child: Icon (
Icons.yourIcon
)
Material(
color: Colors.transparent,
elevation: 10,
child: Icon(
icons.add,
),
),
Container(
width: 30,
height: 30,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(100),
boxShadow: const [
BoxShadow(color: Colors.grey, blurRadius: 1),
],
),
child: const Icon(
FontAwesomeIcons.checkCircle,
size: 30,
color: Colors.green,
),
),
If the container size is the same as the icon size, then 3 pixels will be always downward, This is because I don't know. but this solution will clear it.
Make sure that the container size will increase by 3 pixels with icons size.
Container(
width: 33,
height: 33,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(100),
boxShadow: const [
BoxShadow(color: Colors.grey, blurRadius: 1),
]),
child: const Icon(
FontAwesomeIcons.checkCircle,
size: 30,
color: Colors.green,
),
),
base on this answer you can use this code and maybe add some change
import 'package:flutter/material.dart';
class IconShadowView extends Icon {
const IconShadowView(super.icon,
{super.key,
super.color,
super.semanticLabel,
super.shadows,
super.size,
super.textDirection});
#override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Positioned(
left: 1.0,
top: 2.0,
child: Icon(
icon,
color: Colors.black,
key: key,
semanticLabel: semanticLabel,
shadows: shadows,
size: size,
textDirection: textDirection,
),
),
super.build(context),
],
);
}
}
Are you able or is there a way to change the color of the shadow made by the FloatingActionButton.extended or any other floating button ?
You can try this way:
floatingActionButton: FloatingActionButton(
onPressed: () {},
backgroundColor: Colors.red,
elevation: 0,
child: Container(
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.all(
Radius.circular(100),
),
boxShadow: [
BoxShadow(
color: Colors.purple.withOpacity(0.3),
spreadRadius: 7,
blurRadius: 7,
offset: Offset(3, 5),
),
],
),
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: Container(
height: 70,
width: 70,
margin: const EdgeInsets.only(bottom: 10.0),
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: const BorderRadius.all(
Radius.circular(100),
),
boxShadow: [
BoxShadow(
color: MyColors.myWhite.withOpacity(0.3),
spreadRadius: 6,
blurRadius: 6,
offset: const Offset(0.5, 0.5),
),
],
),
child: FittedBox(
child: FloatingActionButton(
onPressed: (){},
backgroundColor: MyColors.myGreen,
elevation: 10,
child: const Icon(Icons.add,
color: MyColors.myWhite,
size: 18,
shadows: [Shadow(
color: MyColors.myWhite,
offset: Offset(0.2, 0.5),
blurRadius: 5.0,
)],
),
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: (){},
backgroundColor: Color(0xf0004451),
elevation: 10,
child: Container(
padding: const EdgeInsets.all(14.0),
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.all(
Radius.circular(60),
),
boxShadow: [
BoxShadow(
color: Color(0xffE1E8EB).withOpacity(0.35),
spreadRadius: 8,
blurRadius: 8,
offset: const Offset(1, 1),
),
],
),
child: const Icon(Icons.add,
color: Color(0xffE1E8EB),
size: 18,
shadows: [Shadow(
color: Color(0xffE1E8EB),
offset: Offset(0.2, 0.5),
blurRadius: 5.0,
)],
),
),
),
I need to stack widgets like this:
I wrote the code below. However the coins are coming one after another with some default padding. How can I get something like the image above?
Row(
children: <Widget>[
Icon(
Icons.monetization_on, size: 36.0,
color: const Color.fromRGBO(218, 165, 32, 1.0),
),
Icon(
Icons.monetization_on, size: 36.0,
color: const Color.fromRGBO(218, 165, 32, 1.0),
),
],
),
You can use a Stack with Positioned to achieve this:
class StackExample extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(),
body: new Container(
padding: const EdgeInsets.all(8.0),
height: 500.0,
width: 500.0,
// alignment: FractionalOffset.center,
child: new Stack(
//alignment:new Alignment(x, y)
children: <Widget>[
new Icon(Icons.monetization_on, size: 36.0, color: const Color.fromRGBO(218, 165, 32, 1.0)),
new Positioned(
left: 20.0,
child: new Icon(Icons.monetization_on, size: 36.0, color: const Color.fromRGBO(218, 165, 32, 1.0)),
),
new Positioned(
left:40.0,
child: new Icon(Icons.monetization_on, size: 36.0, color: const Color.fromRGBO(218, 165, 32, 1.0)),
)
],
),
),
)
;
}
}
And this how you get some nice shadow drop so the icon stands out more:
class StackExample extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(),
body: new Container(
padding: const EdgeInsets.all(8.0),
height: 500.0,
width: 500.0,
// alignment: FractionalOffset.center,
child: new Stack(
//alignment:new Alignment(x, y)
children: <Widget>[
new Container(
decoration: new BoxDecoration(
borderRadius: BorderRadius.circular(25.0),
boxShadow: [
new BoxShadow(
blurRadius: 5.0,
offset: const Offset(3.0, 0.0),
color: Colors.grey,
)
]
),
child: new Icon(Icons.monetization_on, size: 36.0, color: const Color.fromRGBO(218, 165, 32, 1.0))),
new Positioned(
left: 20.0,
child: new Container(
decoration: new BoxDecoration(
borderRadius: BorderRadius.circular(25.0),
boxShadow: [
new BoxShadow(
blurRadius: 5.0,
offset: const Offset(3.0, 0.0),
color: Colors.grey,
)
]
),
child: new Icon(Icons.monetization_on, size: 36.0, color: const Color.fromRGBO(218, 165, 32, 1.0))),
),
new Positioned(
left:40.0,
child: new Container(
decoration: new BoxDecoration(
borderRadius: BorderRadius.circular(25.0),
boxShadow: [
new BoxShadow(
blurRadius: 5.0,
offset: const Offset(3.0, 0.0),
color: Colors.grey,
)
]
)
,child: new Icon(Icons.monetization_on, size: 36.0, color: const Color.fromRGBO(218, 165, 32, 1.0))),
)
],
),
),
)
;
}
}
As of November 2019 I'd like to add a second solution:
Using package: https://pub.dev/packages/assorted_layout_widgets
var widget1 = ...;
var widget2 = ...;
RowSuper(
children: [widget1, widget2],
innerDistance: -20.0,
);
This will overlap row cells by 20 pixels.
The difference from this solution to the one using Stack is that Positioned widgets in a Stack don't occupy space. So you can't make the Stack the size of its contents, unless you know their sizes in advance. However, the RowSuper will have the size of all of its children widgets.
Note, there is also a ColumnSuper. Also note I am the author of this package.
I wanted something without dependencies and without hardcoded layout.
You could enhance by making overlap use a media query to overlap in terms of %.
Widget overlapped() {
final overlap = 10.0;
final items = [
CircleAvatar(child: Text('1'), backgroundColor: Colors.red),
CircleAvatar(child: Text('2'), backgroundColor: Colors.green),
CircleAvatar(child: Text('3'), backgroundColor: Colors.blue),
];
List<Widget> stackLayers = List<Widget>.generate(items.length, (index) {
return Padding(
padding: EdgeInsets.fromLTRB(index.toDouble() * overlap, 0, 0, 0),
child: items[index],
);
});
return Stack(children: stackLayers);
}
Here is my code on Profile Picture overlapped by camera image in flutter.
Output:
Click here to view output image
Container(
constraints: new BoxConstraints(
maxHeight: 200.0,
maxWidth: 200.0
),
padding: new EdgeInsets.only(left: 16.0, bottom: 8.0, right: 16.0),
decoration: new BoxDecoration(
shape: BoxShape.circle,
image: new DecorationImage(
image: new AssetImage('assets/images/profile.png'),
fit: BoxFit.cover,
),
),
child: Stack(
children: [
new Positioned(
right: 0.0,
bottom: 3.0,
child: Container(
constraints: new BoxConstraints(
maxHeight: 50.0,
maxWidth: 50.0
),
decoration: new BoxDecoration(
boxShadow: [
BoxShadow(
color:Color(0xFFdedede),
offset: Offset(2,2)
),
],
color: Colors.white,
shape: BoxShape.circle,
),
child: GestureDetector(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(
Icons.photo_camera,
size: 34,
color: Color(0xFF00cde7),
),
),
),
),
),
],
),
)
Wraping your elements with OverflowBox and giving the maxWidth value will achieve this effect.
The following can be used in a row or a listview
return SizedBox(
width: 35, //--> list children will be 35 in width
child: OverflowBox(
maxWidth: 50, // --> allowing the child to overflow will cause overlap between elements
child: Container(
width: 50,
child: Text((index + 1).toString()),
),
),
);
You could try my package (signed_spacing_flex). It's exactly the same as a normal Row (or Column and Flex). But it also lets you set negative spacing which causes its children to overlap. You can also set which children should be on top when they overlap.
In your case it would be something like:
SignedSpacingRow(
spacing: -12.0,
stackingOrder: StackingOrder.lastOnTop,
children: <Widget>[
Icon(
Icons.monetization_on, size: 36.0,
color: const Color.fromRGBO(218, 165, 32, 1.0),
),
Icon(
Icons.monetization_on, size: 36.0,
color: const Color.fromRGBO(218, 165, 32, 1.0),
),
],
),
It also works with expanded children if you need.
Reverse variant based on #Lee Higgins
const size = 32.0;
const overlap = size - 6.0;
final containers = [
Container(
decoration: BoxDecoration(
color: Colors.grey[300],
shape: BoxShape.circle,
),
width: size,
height: size,
),
Container(
decoration: BoxDecoration(
color: Colors.grey[400],
shape: BoxShape.circle,
),
width: size,
height: size,
),
];
List<Widget> stackLayers = List<Widget>.generate(containers.length, (index) {
return Padding(
padding: EdgeInsets.fromLTRB(0, 0, index * overlap, 0),
child: containers[index],
);
});
return Stack(alignment: AlignmentDirectional.topEnd, children: stackLayers);
Stack is very much confusing.
The best solution is to use enter link description here
I'm trying to use sIFR on my menu and on my headers... but only one call works... the others that I put after never appear :(...
Can somebody help me ?
Note : I'm using the r436 and below is my code ...
var segoe = {
src: 'pathto/segoe.swf',
ratios: [7, 1.58, 8, 1.49, 10, 1.5, 11, 1.45, 16, 1.46, 21, 1.44, 22, 1.41, 27, 1.42, 30, 1.41, 32, 1.4, 35, 1.41, 36, 1.4, 38, 1.39, 41, 1.4, 58, 1.39, 65, 1.38, 66, 1.39, 102, 1.38, 104, 1.37, 106, 1.38, 107, 1.37, 108, 1.38, 109, 1.37, 110, 1.38, 112, 1.37, 114, 1.38, 120, 1.37, 121, 1.38, 1.37]
};
sIFR.activate(segoe);
sIFR.replace(segoe, {
selector: '#header ul li a span.title',
css: ['.sIFR-root { text-align: center; font-size:13px; letter-spacing:2; font-weight: bold; text-transform:uppercase; cursor: pointer; color:#FFFFFF; background-color:#0C2C39; margin:0 3px; }'],
wmode: 'transparent'
});
sIFR.replace(segoe, {
selector: 'h1',
css: ['.sIFR-root { text-align: center; font-size:13px; letter-spacing:2; font-weight: bold; text-transform:uppercase; cursor: pointer; color:#000; background-color:#fff; margin:0 3px; }']
});
Okay I feel stupid now...
I wasn't properly calling the "sifr-config.js" file...
-_-"
Sorry !