I have used ClipRRect for rounded corners in the UI. The ClipRRect wraps topContent and bottomContent are a stack and a Column respectively. But, the bottom corners are not round. What may be the reason behind this?
The cardModel class is used to store the image path in this case.
class FeaturedCard extends StatelessWidget {
final FeaturedCardModel cardModel;
final double parallaxPercent;
FeaturedCard({
this.cardModel,
this.parallaxPercent = 0.0, //default value
});
#override
Widget build(BuildContext context) {
final topContent = Stack(
children: <Widget>[
Container(
padding: EdgeInsets.only(
left: 10.0,
),
height: MediaQuery.of(context).size.height * 0.3,
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage(cardModel.imgUrl),
fit: BoxFit.fill,
),
)),
],
);
final bottomContentText = Text(
'This is the sample text',
style: TextStyle(fontSize: 18.0),
);
final bottomContent = Container(
height: MediaQuery.of(context).size.height * 0.5,
width: MediaQuery.of(context).size.width,
color: Colors.white,
padding: EdgeInsets.all(40.0),
child: Center(
child:
bottomContentText,
),
);
return ClipRRect(
borderRadius: BorderRadius.circular(16.0),
child: Column(
children: <Widget>[
topContent,
bottomContent,
],
),
);
}
}
If you go to Flutter Inspector and do "Toggle Debug Paint" you will see that the clipping occurs in the blue area below.
You can fix it by giving a size to your clipper.
return SizedBox(
height: MediaQuery.of(context).size.height * 0.8,
child: ClipRRect(
borderRadius: BorderRadius.circular(16.0),
child: Column(
children: <Widget>[
topContent,
//bottomContent,
],
),
),
);
The column that is the child of ClipRRect is taking as much space as it can get. so the border radius is applied to the bottom of the screen.
to solve that you just need to set mainAxisSize property of Column to MainAxisSize.min:
return ClipRRect(
borderRadius: BorderRadius.circular(16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
topContent,
bottomContent,
],
),
);
Related
I am currently learning flutter and have come across an issue where the card is not staying within the boundaries of Column, but is not causing an overflow. My goal is to have the card positioned at the bottom and with Text positioned above the card.
Here is my code:
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Stack(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height,
child:
Image.asset("assets/testimage.jpg", fit: BoxFit.cover)),
Positioned(
bottom: 10.0,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0)),
child: Text(
"A description would be going here, this is just placeholder text.",
style: TextStyle(fontSize: 30),
),
),
)
],
),
],
),
),
);
}
}
and an image example of the problem and desired outcome
Problem
Desired Outcome
You need to define - right: 1.0, left: 1.0, also along with bottom in Positioned. widget.
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Stack(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height,
child: Image.network("https://placeimg.com/640/480/any",
fit: BoxFit.cover)),
Positioned(
bottom: 1.0,
right: 1.0,
left: 1.0,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0)),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
"A description would be going here, this is just placeholder text.",
style: TextStyle(fontSize: 30),
),
),
),
)
],
),
],
),
);
}
Output:
how to fit my CustomPaint to parent widget?
return new Container(
color: Color(0xfffff4f0),
child: new Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
new Expanded(
flex: 6,
child: FittedBox(
fit: BoxFit.contain,
child: widget CustomePaint() // Containers(),
)),
new Expanded(
flex: 4,
)
)
)
fit: BoxFit.contain works for
Container(
height: 30,
width: 10
)
but not work with CustomePaint() where i draw on canvas rectangle:
canvas.drawRect(new Rect.fromLTWH(0, 0, 10 , 30), new Paint()..color =
Colors.red);
It seems you've provided just a part of code needed.
I've tried almost your's code and it worked just fine. I've used another colors and added a border to CustomPaint to better see where it is drawn.
Widget getRootView() {
return Container(
color: Colors.green,
child: Column(crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisSize: MainAxisSize.max, children: <Widget>[
Expanded(
flex: 2,
child: CustomPaint(painter: Painter3()),
),
Expanded(
flex: 1,
child: Container(
color: Colors.red,
child: Center(child: Text("3")),
),
)
]));
}
class Painter3 extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
canvas.drawRect(Offset(10, 10) & Size(size.width - 20, size.height - 20), Paint()..color = Colors.blue);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
What I'v get here is:
When creating a Card (for example using the code from the Docs) , how can I anchor a FAB to the Card (the green circle in the image below), like in this question for Android.
I saw a similar question for attaching a FAB to the AppBar, but the solution relies on the AppBar being a fixed height. When using a Card, the height isn't fixed ahead of time so the same solution can't be used.
You can place the FloatingActionButton in an Align widget and play with the heightFactor property.
For example:
class MyCard extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Card(
child: Column(
children: <Widget>[
SizedBox(height: 100.0, width: double.infinity),
Align(
alignment: Alignment(0.8, -1.0),
heightFactor: 0.5,
child: FloatingActionButton(
onPressed: null,
child: Icon(Icons.add),
),
)
],
),
);
}
}
Correct solution for anchor FAB.
Another solution using stack and container. FAB's place is based on its sibling Container widget's size and clicks/taps work properly.
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: MyWidget(),
),
);
}
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Container(
padding: EdgeInsets.only(bottom: 28),
child: Container(
width: double.infinity,
height: 150,
color: Color.fromRGBO(55, 55, 55, 0.2),
padding: EdgeInsets.all(15),
child: Text(
'Any container with bottom padding with half size of the FAB'),
),
),
Positioned(
bottom: 0,
right: 10,
child: FloatingActionButton(
child: Icon(
Icons.play_arrow,
size: 40,
),
onPressed: () => print('Button pressed!'),
),
),
],
),
);
}
}
CodePan link for anchor FAB
The correct solution is to use a "Stack" and "Positioned" widged like:
return Stack(
children: <Widget>[
Card(
color: Color(0xFF1D3241),
margin: EdgeInsets.only(bottom: 40), // margin bottom to allow place the button
child: Column(children: <Widget>[
...
],
),
Positioned(
bottom: 0,
right: 17,
width: 80,
height: 80,
child: FloatingActionButton(
backgroundColor: Color(0xFFF2638E),
child: Icon(Icons.play_arrow,size: 70,)
),
),
],
);
I would like to control the profile image size, and get it rounded instead of oval as shown below.
Changing the height and/or the width values doesn't affect neither the size nor the ratio, also the weird thing is when I change the margin parameter it changes the oval shape radius.
new UserAccountsDrawerHeader(
decoration: BoxDecoration(color: Colors.white),
currentAccountPicture: new Container(
margin: const EdgeInsets.only(bottom: 40.0),
width: 10.0,
height: 10.0,
decoration: new BoxDecoration(
shape: BoxShape.circle,
image: new DecorationImage(
fit: BoxFit.fill,
image: new NetworkImage(
"https://example.com/assets/images/john-doe.jpg",
),
),
),
),
accountName: new Container(
...
),
accountEmail: new Container(
...
),
onDetailsPressed: () {
...
},
),
What am I doing wrong ?
Update: The above way of doing is a workaround to the CircleAvatar that didn't give any control on the image size. If you tried CircleAvatar in some different way that gives control on image size, please share it to help.
Use This code for network image:
new CircleAvatar(
radius: 60.0,
backgroundColor: const Color(0xFF778899),
backgroundImage: NetworkImage("Your Photo Url"), // for Network image
),
Use this for asset Image:
new CircleAvatar(
radius: 60.0,
backgroundColor: const Color(0xFF778899),
child: new Image.asset(
'images/profile.png',
), //For Image Asset
),
If you use backgroundImage as the image provider for CircleAvatar then changing the radius property indeed has no effect. From the source circle_avatar.dart it can be observed the image is being rendered as BoxFit.cover DecorationImage(image: backgroundImage, fit: BoxFit.cover) - and in user_accounts_drawer_header.dart the currentAccountPicture is hardcoded to be a 72.0 pixel SizedBox so the image will always be 72.0px in dimensions.
https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/material/user_accounts_drawer_header.dart#L57
https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/material/circle_avatar.dart#L203
Hopefully the Flutter team adds some level of control to this in the future.
Not an answer, just more info that hopefully helps someone.
Try This:
import 'package:flutter/material.dart';
class AppDrawer extends StatefulWidget {
#override
_AppDrawerState createState() => new _AppDrawerState();
}
class _AppDrawerState extends State<AppDrawer> {
#override
Widget build(BuildContext context) {
return new Drawer(
child: Center(
child: Column(
children: <Widget>[
new UserAccountsDrawerHeader(
decoration: BoxDecoration(color: Colors.white),
currentAccountPicture: new CircleAvatar(
radius: 50.0,
backgroundColor: const Color(0xFF778899),
backgroundImage:
NetworkImage("http://tineye.com/images/widgets/mona.jpg"),
),
),
],
),
),
);
}
}
This is the screenshot of output:
Wrap your image in a CircleAvatar widget. It’s made for such purposes.
You put the margin inside the Container of the image while you have to use the margin parameter of the UserAccountDrawerHeader, this is why your image became an oval:
UserAccountsDrawerHeader(
decoration: BoxDecoration(color: Colors.white),
margin: EdgeInsets.only(bottom: 40.0),
currentAccountPicture: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.fill,
image:
NetworkImage("https://via.placeholder.com/150"))),
),
accountName: new Container(
child: Text(
'Name',
style: TextStyle(color: Colors.black),
)),
accountEmail: new Container(
child: Text(
'Email',
style: TextStyle(color: Colors.black),
)),
),
You can create your own header:
DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue
),
child: ListView(
children: [
return ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: Image.asset('images/myImage.jpg'),
),
//These can go here or below the header with the same background color
Text("user name"),//customize this text
Text("useremail#example.com"),
//...additional header items here
],
)),
I found a solution!!! at least thats what worked for me
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
// Side menu
drawer: new Drawer(
child: GestureDetector(
onTap: () {},
child: ListView(
children: <Widget>[
new UserAccountsDrawerHeader(
accountName: new Text('Hymn +'),
accountEmail: new Text('johndoe#gmail.com'),
currentAccountPicture: new CircleAvatar(
backgroundImage: new NetworkImage(
'https://miro.medium.com/max/1400/1*uC0kYhn8zRx8Cfd0v0cYQg.jpeg'),
),
),
],
),
),
),
);
}
}
This works for me:
DrawerHeader(
decoration: BoxDecoration(color: Colors.blue),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
/*CircleAvatar(
radius: 50.0,
backgroundColor: const Color(0xFF778899),
child: new Image.asset('assets/images/profile_image.png'), //For Image Asset
),*/
Container(
height: 110,
child: ClipRRect(
borderRadius: BorderRadius.circular(100.0),
child: Image.asset('assets/images/profile_image.png'),
),
),
//These can go here or below the header with the same background color
//Divider(height: 1.0, thickness: 1.0, color: Colors.black),
SizedBox(height: 9.0),
Text("user name"),
//...additional header items here
],
),
),
I am using Flutter for my app development.
I would like to overlay a poster image view on top of a background image just like in this screenshot below.
The code snippet below does this, but it requires me to also position every other widget including the movie title, release date, etc based on poster's position and background image's position, which is not reliable across several devices and orientation. Is there an example or suggestion to solve this problem?
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new PlatformAdaptiveAppBar(
title: new Text(widget.movie.title),
),
body: new Container(
constraints: new BoxConstraints.expand(),
child: new Stack(
children: <Widget>[
new Container(
child: new Image(
image: new AdvancedNetworkImage(
movieGridUtil.getUrlFromPath(widget.movie.backdrop_path,
MovieGridImageTypes.BACKDROP),
useMemoryCache: false,
useDiskCache: true)),
constraints: new BoxConstraints.expand(height: 250.0),
),
new Positioned(
left: 12.0,
top: 220.0,
child: new Image(
width: 100.0,
height: 150.0,
image: new AdvancedNetworkImage(
movieGridUtil.getUrlFromPath(widget.movie.poster_path,
MovieGridImageTypes.POSTER),
useMemoryCache: false,
useDiskCache: true),
)),
],
)),
);
}
Create Stack
Then inside Stack add Column and make full layout without the poster.
Then as a second Child of Stack, add this combination:
new Stack(
children: [
new Column(
children: _layout()
new Positioned(
top:200,
left:50,
child: _child // or optionaly wrap the child in FractionalTranslation
)]
)
)
Stack(
children: <Widget>[
Container(
color: Colors.blue,
height: 200.0,
),
Padding(
padding: const EdgeInsets.only(left: 20.0,right: 20.0, top:160.0),
child: Container(
color: Colors.pink,
height: 150.0,
width: 110.0,
),
)
],
),
By Creating the Stack,
You can add multiple Container, whichever is last added will be on the top.
Stack(
children: <Widget>[
Container(
color: Colors.blue,
height: 200.0,
),
Padding(
padding: const EdgeInsets.only(left: 20.0,right: 20.0, top:160.0),
child: Container(
color: Colors.pink,
height: 150.0,
width: 110.0,
),
)
],
),