I can't seem to find a good way to remove these small white lines, changed the container color to fit with the ModalBottomSheet default background color.
Here is a part of code:
void mountainModalBottomSheet(context){
showModalBottomSheet(context: context, builder: (BuildContext bc){
return Container(
color: Color(0xff757575),
height: MediaQuery.of(context).size.height*.60,
child:Column(
children: [
Container(
width: double.infinity,
height: 225,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(38),
topRight: Radius.circular(38),
),
image:DecorationImage(image: NetworkImage('https://hotelvilatina.hr/wp-content/uploads/2017/11/sljeme.jpg'),
fit: BoxFit.fill),
),
Update
You can use shape property but you need to make sure of providing clipBehavior:hardEdge
showModalBottomSheet(
clipBehavior: Clip.antiAlias, // or hardEdge must
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(38),
topRight: Radius.circular(38),
),
),
context: context,
backgroundColor: Colors.white,
builder: (c) {
return Container();
});
Wrap your Container with ClipRRect widget
showModalBottomSheet(
context: context,
backgroundColor: Colors.transparent, // make sure of it
builder: (c) {
return ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(38),
topRight: Radius.circular(38),
),
child: Container(
color: Colors.white,
));
});
You can use the "shape" property of showModalBottomSheet to give a radius to your bottom sheet. In this way, your bottom sheet has its own radiuses and you will no longer see your white lines.
showModalBottomSheet(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.0),
),
backgroundColor: Colors.white,
...
);
Related
To implement flutter bottomSheetDialog with dynamic height, I wrote a code like this.
void showCustomBottomSheetDialog(Widget body, BuildContext context) {
showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (BuildContext ctx) {
return Wrap(
children: [
Column(
children: [
Container(
height: 24.sp,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0),
topRight: Radius.circular(10.0),
),
),
),
body,
],
),
],
);
},
);
}
showCustomBottomSheetDialog(
Container(
child: Column(
children: [
TextFormField(),
Text('asdfasdfds'),
Text('asdfasdfds'),
Text('asdfasdfds'),
],
),
),
context,
);
But with this code, the displayed bottomSheet did not have a rounded corner...
Could you tell me what is a problem of my code...?
create rounded corner manually
eg:
showModalBottomSheet(
isScrollControlled: true,
context: context,
backgroundColor: Colors.transparent,
builder: (contex) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius:
const BorderRadius.vertical(top: Radius.circular(18))),
child: Column(
children: []
....
also you can wrap it with DraggableScrollableSheet to make it scrollable widget
This is because the Container with rounded corner is inside the Column widget.
For this to work ,lift up the Container.
Code now:
showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (BuildContext ctx) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0),
topRight: Radius.circular(10.0),
),
),
child: Column(...)
),
},
);
Actually, we have shape property on showModalBottomSheet and can be used to make rounded corner, like
showModalBottomSheet(
isScrollControlled: true,
context: context,
shape: const RoundedRectangleBorder( //this
borderRadius: BorderRadius.only(
topLeft: Radius.circular(24),
topRight: Radius.circular(24),
),
),
More about showModalBottomSheet
I understand that making a widget reusable is good when you want to de-clutter your code but I think that it also reduces the code readibility and most often it's the properties (like padding,color,shape) of a widget (like Container,Material) which makes up the most clutter.
So, is there a way that I can make properties of a widget reusable rather than the widget itself.
For example, is there a way that I can make properties of this Material:
Material(
elevation: 4.0,
clipBehavior: Clip.hardEdge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0),
bottomLeft: Radius.circular(30.0),
bottomRight: Radius.circular(5.0),
)),
color: Theme.of(context).primaryColorLight,
child: ...
Like this:
Material(
myMaterialProps: props,
child: ...
If you want to reuse your widget, the easiest way would be to create a custom widget, and set default values for the properties that won't change that often and make those properties optional.
To support variations of your widget, you can create factory methods that will receive only the properties that are different.
Here's a quick example (keep in mind it's just an example):
class MyWidget extends StatelessWidget {
final double elevation;
final Clip clipBehaviour;
final Color color;
final Widget child;
MyWidget(this.child, {double elevation, Clip clipBehaviour, Color color})
: elevation = elevation ?? 4,
clipBehaviour = clipBehaviour ?? Clip.hardEdge,
color = color ?? Colors.green;
factory MyWidget.withRedBorder(Widget child) {
return MyWidget(
child,
color: Colors.red,
);
}
#override
Widget build(BuildContext context) {
return Material(
elevation: 4.0,
clipBehavior: Clip.hardEdge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0),
bottomLeft: Radius.circular(30.0),
bottomRight: Radius.circular(5.0),
)),
color: Theme.of(context).primaryColorLight,
child: child);
}
}
Is making your custom Widget fit your situation?
class MyCustomMaterial extends StatelessWidget{
const MyCustomMaterial({
required this.child,
Key? key,
}):super(key:key);
final Widget child;
#override
Widget build(BuildContext context){
return Material(
elevation: 4.0,
clipBehavior: Clip.hardEdge,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0),
bottomLeft: Radius.circular(30.0),
bottomRight: Radius.circular(5.0),
),
),
color: Theme.of(context).primaryColorLight,
child: child,
);
}
}
And use it as:
MyCustomMaterial(
child: ...
I tried to use the Radius.Circular method and I input a minus value, but it doesn't seems to work at all.
Is there a method to do it?
Screenshot
Oh, flutter does use constraints to restrict the AppBar height, in this case the constraint is hardcoded to 56 according to material design guidelines. To make your AppBar like that the only thing that occurs to me is to have your Scaffold's Body like this
body:Container(
color: Colors.lightBlue,
child: Container(
color: Colors.white,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(100), topRight: Radius.circular(100))),
child: Center(
child: Text('Zero'),
),
),
)
We are making the background the same color as the appBar to make that effect. You could also use Stack to achieve the same effect.
You can do this. Make Scaffold background color same as AppBar background color, set elevation to 0 in AppBar and in body use container with border radius.
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
title: Text(
'Home',
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white),
),
elevation: 0,
automaticallyImplyLeading: false,
backgroundColor: Colors.black,
brightness: Brightness.dark,
),
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(24),
topRight: Radius.circular(24)),
color: Colors.white),
child: Container()));
}
I am wondering why a wrapped Inkwell widget is not working on a simple flutter screen. The code is the following:
class SearchButtonState extends State<SearchButton> {
bool folded = true;
#override
Widget build(BuildContext context) {
return AnimatedContainer(
duration: Duration(milliseconds: 400),
width: folded ? 56 : 200,
height: 56,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(32),
color: Color(0xFF88B4E0),
boxShadow: kElevationToShadow[6],
),
child: Row(
children: [
Expanded(
child: Container(
padding: EdgeInsets.only(left: 16),
child: !folded
? TextField(
decoration: InputDecoration(
hintText: 'Search',
hintStyle: TextStyle(color: Colors.blue),
border: InputBorder.none),
)
: null,
),
),
Container(
//fixing splash
child: Material(
type: MaterialType.transparency,
child: Inkwell(
//Fixing the BorderRadius of the Splash
BorderRadius: BorderRadius.only(
topLeft: Radius.circular(folded ? 32 : 0),
topRight: Radius.circular(32),
bottomLeft: Radius.circular(folded ? 32 : 0),
bottomRight: Radius.circular(32),
),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Icon(
folded ? Icons.search : Icons.close,
color: Color(0xFF88B4E0),
),
),
onTap: () {
setState(() {
folded = !folded;
});
},
)))
],
));
}
}
The error is the following: "The argument type 'dynamic' can't be assigned to the parameter type 'widget'". I would appreciate if someone know why do I get this error, since the Inkwell is wrapped.
Change this code Inkwell to InkWell and BorderRadius: to borderRadius:
child: Material(
type: MaterialType.transparency,
child: InkWell(
//Fixing the BorderRadius of the Splash
borderRadius: BorderRadius.only(
...
I want to implement the modal bottom sheet with a webview as a child in it. When I try to do it, the webview gets messed up and the sheet comes on the top of the screen instead of the bottom.
I tried to change the height but nothing really worked.
Pub dependency: flutter_webview_plugin: ^0.3.5
void _showModelSheet() {
showModalBottomSheet(
context: context,
builder: (builder) {
return new Container(
height: screenHeight / 4,
child: new Container(
decoration: new BoxDecoration(
color: Colors.amber,
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(20.0),
topRight: const Radius.circular(20.0))),
child: Container(
child: new MaterialApp(
debugShowCheckedModeBanner: false,
routes: {
"/": (_) => new WebviewScaffold(
url: "https://www.google.com",
),
},
),
),
),
);
});
}
child: RaisedButton(
elevation: 10,
splashColor: Colors.black,
color: Colors.red.shade900.withOpacity(0.7),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(110)),
onPressed: _showModelSheet,
child: Text(
"sheet"),
),
),
I want to make the whole webview to get wrap into the height of the modal bottom sheet.
You are returning a MaterialApp inside another. And the reason is that the plugin you're using forces you to do that.
Better use the oficial Flutter WebView plugin.
webview_flutter: ^0.3.9+1
Then use it like this:
void _showModelSheet() {
showModalBottomSheet(
context: context,
builder: (builder) {
return new Container(
height: MediaQuery.of(context).size.height / 4,
child: new Container(
decoration: new BoxDecoration(color: Colors.amber, borderRadius: new BorderRadius.only(topLeft: const Radius.circular(20.0), topRight: const Radius.circular(20.0))),
child: Container(
child: WebView(
initialUrl: 'https://google.com',
)),
),
);
},
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: RaisedButton(
elevation: 10,
splashColor: Colors.black,
color: Colors.red.shade900.withOpacity(0.7),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(110)),
onPressed: _showModelSheet,
child: Text("sheet"),
),
),
);
}
This is the result: