I'm having trouble making a card that has a transparent white color (opacity 0.4). But, with shadow from the elevation effect.
If I remove the elevation, there's no shadow effect and the card look transparent. But, if I add some elevation, the transparent effect ruined. Here's what I've tried:
Widget cardMenu(String title) {
return Container(
padding: EdgeInsets.symmetric(horizontal: UIComponent.componentPadding),
child: Stack(
alignment: Alignment.topCenter,
children: [
Positioned(
top: -100,
child: Container(
child: Container(
height: 200,
width: 200,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
child: Center(
child: Text(
title,
style: TextStyle(color: Colors.transparent),
),
),
),
)
),
Align(
alignment: Alignment.bottomCenter,
child: Card(
elevation: 0,
color: Colors.white.withOpacity(0.4),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(UIComponent.cardButtonRadius),
),
),
child: Container(
height: 350,
width: 180,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
padding: EdgeInsets.all(UIComponent.widgetPadding),
child: Text(
title,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: UIComponent.h1,
color: UIComponent.neutralDark,
),
),
)
],
),
),
),
)
],
),
);
}
The output of my code:
What I'm expecting to be:
Hii Christophorus Anindityo N
Make a class for BoxShadow property of container.
class CustomBoxShadow extends BoxShadow {
final BlurStyle blurStyle;
const CustomBoxShadow({
Color color = const Color(0xFF000000),
Offset offset = Offset.zero,
double blurRadius = 0.0,
this.blurStyle = BlurStyle.normal,
}) : super(color: color, offset: offset, blurRadius: blurRadius);
#override
Paint toPaint() {
final Paint result = Paint()
..color = color
..maskFilter = MaskFilter.blur(this.blurStyle, blurSigma);
assert(() {
if (debugDisableShadows)
result.maskFilter = null;
return true;
}());
return result;
}
}
And use this class in a Container
Container(
child: Center(
child: Container(
height: 200.0,
width: 300.0
decoration: BoxDecoration(
boxShadow: [
CustomBoxShadow(
color: Colors.black,
offset: Offset(5.0, 5.0),
blurRadius: 5.0,
blurStyle: BlurStyle.outer
)
],
),
child: Text("Transparent Card with Shadow", style:TextStyle(fontSize:15))),
)
)
Now you are good to code :)
Related
How can I make it so that if an image that is rotated and goes outside of its container does not show outside of it?
I would also like that if the image is in a normal position and if it is larger than its container, it will be shown cut off.
By the way, can I do the same treatment with the icons?
Here is my code
class CardList extends StatelessWidget {
const CardList({
Key? key,
required this.text,
required this.subText,
required this.trailing,
}) : super(key: key);
final String text;
final String subText;
final Widget trailing;
#override
Widget build(BuildContext context) {
GlobalKey _container = GlobalKey();
return Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
elevation: 0,
color: Theme.of(context).colorScheme.surfaceVariant,
margin: EdgeInsets.symmetric(horizontal: 0.5.w, vertical: 0.5.h),
child: Row(
children: [
Container(
padding: EdgeInsets.only(left: 10.w),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AutoSizeText(text,
maxLines: 1,
style: Theme.of(context).textTheme.bodyText1),
subText.isNotEmpty
? AutoSizeText(
subText,
maxLines: 1,
style: Theme.of(context)
.textTheme
.subtitle1!
.copyWith(
color: Theme.of(context)
.colorScheme
.onSurfaceVariant,
fontWeight: FontWeight.w500),
)
: const SizedBox(
height: 0,
),
],
),
),
Container(
color: Colors.blue,
height: 100,
child: Transform.translate(
offset: Offset(0.0, 15.0),
child: Transform.rotate(
angle: -3.14 / 12.0,
child: Image.asset(
'assets/images/map.png',
height: 300,
))),
),
],
));
}
}
By using Container's clipBehavior and set it to antiAlias you can make sure the child widget never appear outside of its parent, like this:
Container(
clipBehavior: Clip.antiAlias, // add this
decoration: BoxDecoration(// add this
color: Colors.blue,
),
height: 100,
child: Transform.translate(
offset: Offset(0.0, 15.0),
child: Transform.rotate(
angle: -3.14 / 12.0,
child: Image.asset(
'assets/images/map.png',
height: 300,
))),
),
Try wrapping your image widget inside ClipRRect widget, ClipRRect.
Try below code hope its help to you, refer ClipRRect, just change my image with your image
FittedBox(
child: ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: Container(
constraints: BoxConstraints.tight(const Size(100, 100)),
color: Colors.blue,
child: Transform.translate(
offset: const Offset(0.0, 15.0),
child: Transform.rotate(
angle: -3.14 / 12.0,
child: const FlutterLogo(size: 300),
),
),
),
),
),
Result->
Using ClipRRect Widget will solve that.
If you wrap your image inside a ClipRRect Widget in a rotation position, it will automatically cut the outward edges.
ClipRRect(child: Image.network('your image'))
Also, in a normal image position inside a container, if the corners are rounded and the image is not, you need to put your image inside a ClipRRect widget, and borderRadius option allows you to round your image to match the container radius.
Container(
decoration: BoxDecoration(borderRadius: BorderRadius.circular(5)),
child: ClipRRect(
borderRadius: BorderRadius.circular(5),
child: Image.network('Your Image')
)
)
I have a stack with list of content and custom dialogBox that I created. It contains textfeild. When I click the textfeild, keyboard opens and push dialog box way above the keyboard. There is alot of gap between the bottom of the dialog and the start of the keyboard. How can I keep the bottom of dialog stuck to the top the keyboard in a clean manner.
import 'package:flutter/material.dart';
class CombinedHomeView extends StatefulWidget {
// --- Services Headings
#override
_CombinedHomeViewState createState() => _CombinedHomeViewState();
}
class _CombinedHomeViewState extends State<CombinedHomeView> {
_showGrocOrderReviewDialog(Size _deviceSize) {
return Align(
alignment: Alignment.bottomCenter,
child: Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(10),
width: double.infinity,
height: _deviceSize.height * 0.28,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
"How was your last order?",
style: TextStyle(
fontFamily: fontMontserrat,
color: Colors.black87,
),
),
SizedBox(height: 10),
Expanded(
child: Container(
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.grey.withOpacity(0.2),
borderRadius: BorderRadius.all(
Radius.circular(_deviceSize.height * 0.02),
),
),
child: SingleChildScrollView(
child: TextField(
maxLines: 5,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Add additional remarks',
hintStyle: TextStyle(
fontSize: _deviceSize.height * 0.015,
fontFamily: fontMontserrat,
color: Colors.black38,
),
),
),
),
),
),
SizedBox(height: 10),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(
child: SmallBtn(
passedText: "Cancel",
passedBorderColor: Colors.green,
passedBGColor: Colors.white,
passedFontColor: Colors.brown,
),
),
SizedBox(width: 10),
Expanded(child: SmallBtn(passedText: "Submit")),
],
),
],
),
),
);
}
#override
Widget build(BuildContext context) {
Size _deviceSize = MediaQuery.of(context).size;
return Stack(
alignment: Alignment.center,
children: [
// ------------ List of content
ListView( // few simple widgets here),
// ------------ Dialog
_showGrocOrderReviewDialog(_deviceSize)
],
);
}
}
You can ignore the below code. It is just a code of SmallBtn incase anyone needs it.
import 'package:flutter/material.dart';
// ignore: must_be_immutable
class SmallBtn extends StatelessWidget {
final String passedText;
IconData passedIcon;
Color passedBGColor;
Color passedFontColor;
Color passedBorderColor;
bool isShadowEnabled;
SmallBtn({
#required this.passedText,
this.passedIcon,
this.passedBGColor,
this.passedFontColor,
this.passedBorderColor,
this.isShadowEnabled,
});
#override
Widget build(BuildContext context) {
isShadowEnabled == null
? isShadowEnabled = false
: isShadowEnabled = isShadowEnabled;
final deviceSize = MediaQuery.of(context).size;
return Container(
// alignment: Alignment.bottomLeft,
// width: deviceSize.width * 0.5 + passedText.length * 3,
padding: EdgeInsets.only(left: 10, right: 10, top: 5, bottom: 5),
height: deviceSize.height * 0.04,
decoration: BoxDecoration(
color: passedBGColor == null ? Colors.brown : passedBGColor,
borderRadius: BorderRadius.all(
Radius.circular(
deviceSize.height * 0.02,
),
),
border: Border.all(
color: passedBorderColor == null
? Colors.transparent
: passedBorderColor,
),
boxShadow: [
isShadowEnabled
? BoxShadow(
color: Colors.brown,
blurRadius: 10.0, // has the effect of softening the shadow
spreadRadius: 1.0, // has the effect of extending the shadow
offset: Offset(
0.0, // horizontal
1.0, // vertical
),
)
: BoxShadow()
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
passedIcon != null
? Icon(
passedIcon,
color: Colors.white,
size: deviceSize.height * 0.02,
)
: Container(),
passedIcon != null
? SizedBox(width: deviceSize.width * 0.01)
: SizedBox(),
Text(
passedText,
style: TextStyle(
fontSize: deviceSize.height * 0.018,
fontFamily: "Montserrat",
color: passedFontColor != null ? passedFontColor : Colors.white,
),
),
],
),
);
}
}
Why are you using a stack? If you replace the stack with a column your dialog will not be pushed to the top of the screen.
If I just throw together an image and some text in a rounded-corner rectangle, the user will not know that they can "click here". But I don't have to bake my own solution. InkWell covers this scenario, complete with a nice shadow.
I am positioning
a custom clickable icon using the
InkWell
class, itself requiring to be inside an
Ink
instance.
import 'package:flutter/material.dart';
const boat_url = ('https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/'
'Segelboot_Bodensee_Mainau_%28Foto_Hilarmont%29.JPG/'
'182px-Segelboot_Bodensee_Mainau_%28Foto_Hilarmont%29.JPG');
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Image',
home: Scaffold(
backgroundColor: Colors.grey,
body: MyImage(),
)));
}
class MyImage extends StatelessWidget {
MyImage({Key key,});
#override
Widget build(BuildContext context) {
Size sz = MediaQuery.of(context).size * 0.4;
double border = 4;
return Stack(children: [
Positioned(
top: 100,
left: 100,
width: sz.width,
height: sz.height,
child: Material(
child: Ink(
decoration: BoxDecoration(
boxShadow: <BoxShadow>[
new BoxShadow(
color: Colors.red,
blurRadius: 10.0,
offset: new Offset(30.0, 20.0),
),
],
border: Border.all(
color: Colors.blue,
width: border,
),
borderRadius: BorderRadius.circular(40),
),
child: InkWell(
onTap: (){/*..*/},
child: Column(
children: [
Container(
height: 4 * (sz.height - 2 * border) / 5,
alignment: Alignment.center,
child: Image.network(boat_url),
),
Container(
height: (sz.height - 2 * border) / 5,
child: FittedBox(
clipBehavior: Clip.antiAlias,
alignment: Alignment.centerLeft,
fit: BoxFit.fitHeight,
child: Text('A long descriptive sentence')),
)
],
)),
),
)),
]);
}
}
1- I'm not actually using Colors.white, and the Scaffold itself has
backgroundColor: Colors.grey. Where is the white background coming from?
2- When we talk of a "shadow", I'm expecting the shadow to be behind
the ink/inkwell object. Why does the shadow appear in front?
Related: 1
That white color is from the Material widget, to remove that you can use type param.
Material(
type: MaterialType.transparency,
child: Container(),
);
Here is code to achieve the custom button
Video link
Scaffold(
backgroundColor: Colors.blueGrey,
body: SafeArea(
child: Container(
decoration: BoxDecoration(
color: Colors.green.shade200,
border: Border.all(color: Colors.green),
borderRadius: BorderRadius.circular(5),
boxShadow: [
BoxShadow(
blurRadius: 5,
spreadRadius: 2,
color: Colors.black26,
)
]),
margin: const EdgeInsets.all(20),
child: Material(
type: MaterialType.transparency,
child: InkWell(
onTap: () {},
splashColor: Colors.black26,
child: IntrinsicHeight(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Column(mainAxisSize: MainAxisSize.min, children: [
Image.asset(
'assets/images/marked_tyre_base.png',
fit: BoxFit.cover,
width: 80,
height: 80,
),
const SizedBox(
height: 10,
),
Text(
'Tyre 1',
style: TextStyle(color: Colors.white),
)
]),
),
),
),
),
),
),
);
Screenshot:
Create a class, ImageTextButton:
class ImageTextButton extends StatelessWidget {
final VoidCallback onPressed;
final ImageProvider image;
final double imageHeight;
final double radius;
final Widget text;
ImageTextButton({
#required this.onPressed,
#required this.image,
this.imageHeight = 200,
this.radius = 28,
#required this.text,
});
#override
Widget build(BuildContext context) {
return Card(
elevation: 8,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(radius)),
clipBehavior: Clip.hardEdge,
child: InkWell(
onTap: onPressed,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Ink.image(
image: image,
height: imageHeight,
fit: BoxFit.cover,
),
SizedBox(height: 6),
text,
SizedBox(height: 6),
],
),
),
);
}
}
Usage:
ImageTextButton(
onPressed: () {},
image: AssetImage('chocolate_image'),
text: Text('Chocolate'),
)
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,
),
),
],
),
),
);
}
}
My Home Page screen is not responsive at different size of the screens.
It got overlapped on other widgets.
I used MediaQuery.
How to resove this issue?
IOS Device
Android device
Code:
Size get size => Size(MediaQuery.of(context).size.width * 0.8,
MediaQuery.of(context).size.width * 0.8);
double _rotote(int index) => (index / widget.items.length) * 2 * pi;
build method:
Center(
child: Container(
// alignment: Alignment.center,
height: size.height/1.1,
width: size.width/1.1,
decoration: BoxDecoration(
shape: BoxShape.circle,
boxShadow: [BoxShadow(blurRadius: 20, color: Colors.black38)],
//border: Border.all(color: Colors.black)
),
child: Transform.rotate(
angle: -(widget.current + widget.angle) * 2 * pi,
child: Stack(
alignment: Alignment.center,
children: <Widget>[
for (var luck in widget.items) ...[_buildCard(luck)],
for (var luck in widget.items) ...[_buildImage(luck)],
],
),
),
),
);
WHEEL CARD:
_buildCard(Luck luck) {
var _rotate = _rotote(widget.items.indexOf(luck));
var _angle = 2 * pi / widget.items.length;
return Transform.rotate(
angle: _rotate,
child: ClipPath(
clipper: _LuckPath(_angle),
child: Container(
height:size.height/1.1,
width: size.width/1.1,
decoration: BoxDecoration(
// border: Border.all(color: Colors.black),
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [luck.color, luck.color])),
),
),
);
}
IMAGE ON WHEEL
_buildImage(Luck luck) {
var _rotate = _rotote(widget.items.indexOf(luck));
return Transform.rotate(
angle: _rotate,
child: Container(
height: size.height,
width: size.width,
alignment: Alignment.topCenter,
child: ConstrainedBox(
constraints:
BoxConstraints.expand(height: size.height / 3, width: 44),
child: Image.asset(luck.asset),//Image.asset("asset/image/wheel.png")
),
),
);
}
}
These above methods are defined in a StatefulWidget class BoardView.dart
HomePage.dart
Center(
child: Column(
children: <Widget>[
ArrowView(),// for upper arrow
Stack(
alignment: Alignment.center,
children: <Widget>[
BoardView(items: _items, current: _current, angle: _angle),
_buildSpin(),
],
),
_buildResult(_value),
],
),
);
_buildSpin
_buildSpin() {
return Material(
color: Colors.white,
shape: CircleBorder(),
child: InkWell(
customBorder: CircleBorder(),
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
border: Border.all(color: Colors.white),
color: Colors.blue,
borderRadius: BorderRadius.circular(80)
),
height: 70,
width: 70,
child: Text(
"SPIN",
style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.bold, color: Colors.white),
),
),
onTap: (){},
),
);
}
I think you can have a look at this package. I have used it on one of my projects and it really makes life easy when dealing with different screens from mobile to tablets.
you can use FractionallySizedBox with widthFactor or heightFactor, see: https://www.youtube.com/watch?v=PEsY654EGZ0
and for orientation you can wrap your widget with OrientationBuilder: https://flutter.dev/docs/cookbook/design/orientation