I just started learning Dart and Flutter development and have been playing with BoxShadow.
As you can see in the image below, the shadow for the Bar, Boo and Faz cards are cutoff while that for the text box shows up.
How do I ensure the shadows for the cards show up correctly?
Here's my code:
import 'package:flutter/material.dart';
import 'package:reminder_app/constants.dart';
class Body extends StatelessWidget {
Widget _buildBanner(size) {
return Container(
height: size.height * 0.7,
decoration: BoxDecoration(
color: kPrimaryColor,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(36),
bottomRight: Radius.circular(36),
),
),
);
}
Widget _buildCard(text) {
return Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.teal[200],
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
offset: Offset(10, 10),
blurRadius: 25,
color: Colors.black.withOpacity(
0.75,
),
),
],
),
child: Text(text),
);
}
Widget _buildCardGrid() {
return Expanded(
child: GridView.count(
primary: false,
padding: EdgeInsets.symmetric(
vertical: kDefaultPadding * 1.5,
),
crossAxisSpacing: 20,
mainAxisSpacing: 20,
crossAxisCount: 2,
children: <Widget>[
_buildCard("Foo"),
_buildCard("Bar"),
_buildCard("Baz"),
_buildCard("Boo"),
_buildCard("Far"),
_buildCard("Faz"),
],
),
);
}
Widget _buildInputBox() {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
offset: Offset(10, 10),
blurRadius: 25,
color: Colors.black.withOpacity(
0.75,
),
),
],
),
height: 55,
child: TextField(
decoration: InputDecoration(
hintText: "Text Here",
hintStyle: TextStyle(
color: kPrimaryColor.withOpacity(
0.5,
),
),
enabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
),
),
);
}
Widget _buildInteractionContainers(size) {
return Positioned(
child: Container(
margin: EdgeInsets.symmetric(
horizontal: kDefaultPadding * 2,
),
width: size.width,
child: Column(
children: [
_buildInputBox(),
_buildCardGrid(),
],
),
),
);
}
Widget _buildBody(size) {
return SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
height: size.height * 0.7,
child: Stack(
children: <Widget>[
_buildBanner(size),
_buildInteractionContainers(size),
],
),
),
],
),
);
}
#override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return _buildBody(size);
}
}
Bar, Boo and Faz's shadows are cutoff while the shadow for the text box shows up
Edit [Answer]: I was able to fix this by adding clipBehavior: Clip.none to GridView to prevent shadow clipping.
Please try this code, To How to prevent box-shadow from being cut off?
If the box-shadow is muted, make sure that
overflow: visible
Is set to all div tags that contain your element.
I hope this information will be useful to you.
Thank you.
Related
my screen is not getting scrollable. I am using background picture and i want it to be scrollable as well because when i used single child scrollable widget as a parent of container after background picture, it worked by back ground image didn't scrolled.
Stack(children: [
const BackgroundPicture(),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 30,
vertical: 50,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.asset(
'assets/Frame.png',
),
const SizedBox(
height: 60,
),
const SizedBox(
width: 400,
child: Text(
'Where would you like to start',
style: TextStyle(
decoration: TextDecoration.none,
fontSize: 40,
color: Colors.black,
fontWeight: FontWeight.w100),
),
),
const SizedBox(
height: 50,
),
Center(
child: Container(
height: MediaQuery.of(context).size.height * 0.6,
width: MediaQuery.of(context).size.width * 0.8,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: const Color(0xffF3F2F2),
boxShadow: const [
BoxShadow(
color: Color.fromRGBO(0, 0, 0, 0.08),
blurRadius: 20,
spreadRadius: 5,
offset: Offset(0, 3), // changes position of shadow
),
],
),
),
),
],
),
)
]);
You can just wrap your Stack in a SingleChindScrollView Widget, this widgets allows the scroll.
SingleChildScrollView(
child: Stack(
children: [
const BackgroundPicture(),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 30,
vertical: 200,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.asset(
'assets/Frame.png',
),
const SizedBox(
height: 60,
),
const SizedBox(
width: 400,
child: Text(
'Where would you like to start',
style: TextStyle(
decoration: TextDecoration.none,
fontSize: 40,
color: Colors.black,
fontWeight: FontWeight.w100),
),
),
const SizedBox(
height: 50,
),
Center(
child: Container(
height: MediaQuery.of(context).size.height * 0.6,
width: MediaQuery.of(context).size.width * 0.8,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: const Color(0xffF3F2F2),
boxShadow: const [
BoxShadow(
color: Color.fromRGBO(0, 0, 0, 0.08),
blurRadius: 20,
spreadRadius: 5,
offset: Offset(0, 3), // changes position of shadow
),
],
),
),
),
],
),
)
],
),
);
My CSS:
background: linear-gradient(91.97deg, #F8A170 14.73%, #FFCD61 97.52%);
border-radius: 10px;
I want to go with flutter but when I give these colors to the container widget with child elevated button, I can't get the result I want. I made the button style transparent, but still I couldn't solve it.
Based on your image and css, You can simply decorate the style of ElevatedButton.
DecoratedBox(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
gradient: const LinearGradient(
colors: [
Color(0xFFF8A170),
Color(0xFFFFCD61),
],
),
),
child: SizedBox(
width: 400,
height: 75,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
elevation: 0,
primary: Colors.white.withOpacity(0),
padding: const EdgeInsets.all(0),
),
onPressed: () {},
child: const Text(
"Search a room",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 22,
),
),
),
),
),
More about
DecoratedBox and ElevatedButton
Please refer to below example code
Using Elevated Button
LinearGradient yellowLinearGradientValues() {
return LinearGradient(
colors: [Colors.orange, Color(0xffFFB800).withOpacity(0.65)],
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
elevation: 0.0,
padding: EdgeInsets.zero,
primary: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
side: BorderSide(
width: 0.0,
color: Colors.orange,
style: BorderStyle.none,
),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(8.0),
),
gradient: yellowLinearGradientValues(),
),
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 40.0,
vertical: 8.0,
),
child: Text(
"Search a Room" ?? "",
textAlign: TextAlign.start,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 24.0,
),
),
),
),
),
),
);
}
LinearGradient yellowLinearGradientValues() {
return LinearGradient(
colors: [Colors.orange, Color(0xffFFB800).withOpacity(0.7)],
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () {},
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.transparent),
elevation: MaterialStateProperty.all(0.0),
padding: MaterialStateProperty.all(EdgeInsets.zero),
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(8.0),
),
gradient: yellowLinearGradientValues(),
),
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 40.0,
vertical: 8.0,
),
child: Text(
"Search a Room" ?? "",
textAlign: TextAlign.start,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 24.0,
),
),
),
),
),
),
);
}
I have a chat messenger screen which looks like the given screenshot .
As you can see , bottom message is hidden behind the text input area .
The messages are listview , built using streambuilder .
I want the messages above the text input area .
https://i.stack.imgur.com/A82X2.png
return Scaffold(
appBar: AppBarMain(context),
body: Container(
child: Stack(
children: [
chatMessageList(),
Positioned(
bottom: 0,
child: Container(
color: Color(0x54ffffff),
child: Container(
padding: EdgeInsets.symmetric(horizontal: 14, vertical: 20),
width: MediaQuery.of(context).size.width,
child: Row(
children: [
Expanded(
child: TextField(
controller: messageController,
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
hintText: ' Message!...',
hintStyle: TextStyle(color: Colors.white54),
border: InputBorder.none),
),
),
InkWell(
onTap: () {
sendMessage();
},
child: Container(
padding: EdgeInsets.all(9),
height: 40,
width: 40,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0x36FFFFFF),
Color(0xFFFFFFFF)
],
),
borderRadius: BorderRadius.circular(40)),
child: Image.asset('assets/images/send.png')),
)
],
),
),
),
)
],
),
),
);
}
}
Your structure should be something like
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: chatMessageList(),
),
MessageFieldWidget(),
],
)
This will ensure that your chatMessageList will take up all of the space available in the screen and your Message Field will take up only the space that it needs. You don't need to use Positioned or Padding.
I had a problem with my project, i'm trying make container with box shadow on bottom. below that container i want make to new container but they are some separate space between container, i think its because box shadow. so the question is how to make they connect ith no space but the shadow still visible.
pic
here my code :
return Scaffold(
body: SafeArea(
child: Container(
child: ListView(
physics: BouncingScrollPhysics(),
children: <Widget>[
Container(
child: Padding(
padding: const EdgeInsets.all(0.0),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.zero,
topRight: Radius.zero,
),
child: Container(
height: 70.0,
margin: const EdgeInsets.only(
bottom: 6.0), //Same as `blurRadius` i guess
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(5.5),
bottomRight: Radius.circular(5.5),
topLeft: Radius.zero,
topRight: Radius.zero,
),
color: kDarkGreenColor,
boxShadow: [
BoxShadow(
color: Colors.grey,
offset: Offset(0.0, 1.0), //(x,y)
blurRadius: 6.0,
),
],
),
child: ListView.builder(
padding: EdgeInsets.only(left: 10, right: 5),
itemCount: planticos.length,
physics: BouncingScrollPhysics(),
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) {
return Container(
margin: EdgeInsets.only(right: 15, bottom: 6),
height: 40,
width: 70,
decoration: BoxDecoration(
color: kMainColor.withOpacity(0),
image: DecorationImage(
image: AssetImage(planticos[index].image),
),
),
);
}),
),
),
),
),
Container(
margin: EdgeInsets.only(top: 0),
height: 200,
color: kMainColor,
),
],
),
),
),
);
}
use stack.
2nd Container will be visible over 1st Container.
for example...
Stack(
children: <Widget>[
Container(
height: 400,
decoration: BoxDecoration(
color: Colors.green,
),
),
Container(
height: 200,
decoration: BoxDecoration(
color: Colors.green,
boxShadow: [
BoxShadow(
color: Colors.red,
offset: Offset(0.0, 1.0), //(x,y)
blurRadius: 6.0,
),
],
),
),
],
),
You should use the stack widget, see this example:
Stack(
children:[
Container() //which you wanna be under the shadow.
Container() //which you wanna make it's shadow visible.
]
)
Tip: Use Positioned() under the stack to specify the position of containers.
Hi I have a stream builder that lists containers with a button to count down and when the counter hits zero I wanted to hide that single container from the list I can’t figure out how to, if anyone does please help
bool visibility = true;
Widget _dataList() {
if (data != null) {
return StreamBuilder(
stream: data,
builder: (context, snapshot) {
return ListView.builder(
itemCount: snapshot.data.documents.length,
padding: EdgeInsets.all(5.0),
itemBuilder: (context, i) {
return visibility == true
? new Container(
child: Padding(
padding: EdgeInsets.only(top: 5, right: 5, left: 5),
child: Material(
borderRadius: BorderRadius.circular(20),
elevation: 9,
color:
Theme.of(context).cardColor.withOpacity(.95),
shadowColor:
Theme.of(context).accentColor.withOpacity(.5),
child: Container(
padding: EdgeInsets.only(
bottom: 10, right: 10, left: 10, top: 15),
height: 210,
decoration: BoxDecoration(
color: Color(0xFF0B0F1B),
borderRadius: BorderRadius.circular(20),
border: Border.all(
width: 1,
color: Colors.grey.withOpacity(0.5))),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(4.0),
child: Text(
'Number Of Participants :-' +
snapshot.data.documents[i]
.data['numberOfParticipants'],
style: TextStyle(
color: Colors.white, fontSize: 15),
),
),
Padding(
padding: const EdgeInsets.only(top: 7.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 40,
),
Material(
borderRadius:
BorderRadius.circular(20),
elevation: 26,
color: Color(0xFF0B0F1B),
child: Container(
height: 30,
width: 120,
decoration: BoxDecoration(
color: Color(0xFF0B0F1B),
borderRadius:
BorderRadius.circular(20),
border: Border.all(
width: 1,
color: Colors.grey
.withOpacity(0.5))),
child: InkWell(
splashColor: Colors.redAccent,
borderRadius:
BorderRadius.circular(20),
child: Center(
child: Text(
'View',
style: TextStyle(
color: Color(0xFFC77AF3),
fontSize: 18),
)),
onTap: () {
int currentval = int.parse(
snapshot.data.documents[i]
.data[
'numberOfParticipants']);
setState(
() {
currentval--;
snapshot.data.documents[i]
.data[
'numberOfParticipants'] =
currentval.toString();
if (currentval == 0) {
visibility = false;
}
},
);
},
),
),
),
SizedBox(
width: 85,
),
Material(
borderRadius:
BorderRadius.circular(20),
elevation: 26,
color: Color(0xFF0B0F1B),
child: Container(
height: 30,
width: 120,
decoration: BoxDecoration(
color: Color(0xFF0B0F1B),
borderRadius:
BorderRadius.circular(20),
border: Border.all(
width: 1,
color: Colors.grey
.withOpacity(0.5))),
child: InkWell(
splashColor: Colors.greenAccent,
borderRadius:
BorderRadius.circular(20),
child: Center(
child: Text(
'Join',
style: TextStyle(
color: Colors.greenAccent,
fontSize: 18),
)),
onTap: () {
setState(
() {},
);
},
),
),
),
],
),
),
],
),
),
),
),
)
: new Container();
},
);
});
} else {
return Center(child: Text('Nothing yet'));
}
}
this is my code i tried to accomplish the visibility by an empty container because i don't want it to hold a place but the problem is it hides all other containers with it the whole list goes invisible
You can use Opacity with an opacity: of 0.0 to draw make an element hidden but still occupy space.
To make it not occupy space, replace it with an empty Container().
EDIT: To wrap it in an Opacity object, do the following:
new Opacity(opacity: 0.0, child: new Padding(
padding: const EdgeInsets.only(
left: 16.0,
),
child: new Icon(pencil, color: CupertinoColors.activeBlue),
))
Google Developers quick tutorial on Opacity: https://youtu.be/9hltevOHQBw
you can also try
Visibility(
visible: false,
child: child
)
);