Related
I was wondering how can I achieve something like this, this kind of shape?
Here:
class Draw extends StatelessWidget {
const Draw({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SizedBox(
width: 300,
height: 170,
child: Stack(
clipBehavior: Clip.none,
children: [
Center(
child: ClipPath(
clipper: MyClipper(),
child: Container(
width: 300,
height: 170,
color: Colors.black,
),
),
),
Positioned(
left: -20,
child: SizedBox(
height: 170,
child: Center(
child: Material(
elevation: 3,
color: Colors.black,
shadowColor: Colors.white,
borderRadius: BorderRadius.circular(10),
child: const SizedBox(width: 80, height: 80),
),
),
),
)
],
),
),
),
);
}
}
class MyClipper extends CustomClipper<Path> {
#override
Path getClip(Size size) {
final p = Path();
double facotr = 30;
p.moveTo(10, 0);
p.lineTo(10, size.height - 20);
p.quadraticBezierTo(10, size.height, 20, size.height);
p.lineTo(size.width - facotr, size.height - facotr);
p.lineTo(size.width, size.height / 2);
p.lineTo(size.width - facotr, facotr);
p.lineTo(20, 0);
p.quadraticBezierTo(10, 0, 10, 10);
return p;
}
#override
bool shouldReclip(covariant CustomClipper<Path> oldClipper) => true;
}
There is the Paint widget, but also someone made a tool for that wich makes it convienent.
Shape Maker
I was trying to add a border shadow effect to a Container in a way that resembles exactly the same design as in the picture below. My initial idea was of using the CustomPaint class feature to do so. However, it hasn't worked out the way I wanted it to. I would honestly like to know how this can be achieved through the use of the CustomPaint class and I apologize for the code that I've written as I'm still trying to get used to CustomPaint. The code and the pictures are as follows:
This is what I intend to achieve:
This is what I have. You can see that the border goes well beyond where it should be and also, the border at the bottom gets clipped and despite adjusting the bottom padding:
This is the code:
class ProfilePageState extends State<ProfilePage> {
#override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
overlays: [SystemUiOverlay.bottom]);
final height = MediaQuery.of(context).size.height;
final width = MediaQuery.of(context).size.width;
final textScale = MediaQuery.of(context).textScaleFactor * 1.2;
// TODO: implement build
return Scaffold(
body: ListView(
children: [
Container(
height: height * 1,
width: width * 1,
// color: Colors.red,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/filter.png'),
fit: BoxFit.cover)),
child: Column(
......
Padding(
padding: EdgeInsets.only(left: width * 0.035),
child: Container(
width: double.infinity,
height: height * 0.25,
padding: EdgeInsets.only(
left: width * 0.03,
top: height * 0.01,
// bottom: height * 0.01
),
// color: Colors.yellow,
child: ProfilePageFavourite(), //This here is the widget
),
),
],
),
),
],
),
);
}
}
The ProfilePageFavourite widget:
class ProfilePageFavouriteState extends State<ProfilePageFavourite> {
// final List<dynamic> _favouritesList = [
// ];
var favourite = false;
void _onPressed() {
setState(() => favourite = !favourite);
print(favourite);
}
#override
Widget build(BuildContext context) {
final width = MediaQuery.of(context).size.width;
final height = MediaQuery.of(context).size.height;
final textScale = MediaQuery.of(context).textScaleFactor * 1.2;
// TODO: implement build
return ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (context, index) => Stack(
children: [
CustomPaint( //This is where I try using the CustomPaint class
painter: OrangePainter(),
child: Container(
width: width * 0.75,
margin: EdgeInsets.only(right: width * 0.09),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.yellow,
image: DecorationImage(
fit: BoxFit.fitWidth,
image: AssetImage('assets/images/pub screen 1 (1).png'))),
),
),
Positioned(
top: height * 0.16,
child: Container(
height: height * 0.07,
width: width * 0.75,
padding: EdgeInsets.only(top: height * 0.008),
decoration: BoxDecoration(
color: Colors.black38,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(20),
bottomRight: Radius.circular(20))),
child: Column(
children: [
Row(
// mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
padding: EdgeInsets.only(left: width * 0.05),
decoration: BoxDecoration(boxShadow: [
BoxShadow(
color: Colors.red,
blurRadius: 35,
spreadRadius: 8,
offset: Offset(0, 2))
]),
child: Image.asset(
'assets/icons/dine.png',
color: Colors.white,
),
),
SizedBox(
width: width * 0.02,
),
Text(
'Sollicitudin',
textScaleFactor: textScale,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 20,
shadows: [
Shadow(
color: Colors.red,
blurRadius: 10,
offset: Offset(0, 2))
]),
)
],
),
Container(
width: double.infinity,
// color: Colors.red,
padding: EdgeInsets.only(left: width * 0.118),
child: CustomRatingBar(4.5))
],
),
),
),
Positioned(
left: width * 0.58,
top: height * 0.01,
child: Container(
decoration: BoxDecoration(boxShadow: [
BoxShadow(
color: Colors.pink,
blurRadius: 80,
spreadRadius: 6,
)
]),
child: !favourite
? IconButton(
onPressed: _onPressed,
icon: Icon(
Icons.favorite,
// color: Color.fromRGBO(247, 180, 230, 0.8),
color: Colors.pink,
size: 50,
))
: IconButton(
onPressed: _onPressed,
icon: Icon(
Icons.favorite_border_outlined,
color: Colors.pink,
size: 50,
)),
),
),
],
),
itemCount: 5,
);
}
}
The CustomPaint Class
class OrangePainter extends CustomPainter {
OrangePainter();
#override
void paint(Canvas canvas, Size size) {
final rrectBorder =
RRect.fromRectAndRadius(Offset.zero & size, Radius.circular(12));
final rrectShadow =
RRect.fromRectAndRadius(Offset(0, 2) & size, Radius.circular(12));
final shadowPaint = Paint()
..color = Colors.lightGreen
..style = PaintingStyle.stroke
..strokeWidth = 3
..maskFilter = MaskFilter.blur(BlurStyle.solid, 20);
canvas.drawRRect(rrectShadow, shadowPaint);
}
#override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return true;
}
}
I would like to suggest an alternative approach, Custom Paint is very expensive to use in applications. You could instead wrap your container in a Card() then add your shadowColor: Colors.lightGreen set the **shape: ** to the same as your Container() and you should get the result you desire
I have retained the initial customPaint and used it here.This code combines your ProfilePageState and ProfilePageFavourite to give you the appearance below. I've just built it on my phone's dartpad so you can do the editing so it matches. I included comments:
#override
Widget build(BuildContext context) {
return Scaffold(
body: SizedBox(
height: 250,
width: double.infinity,
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: 5,
separatorBuilder: (ctx, index) => const SizedBox(width: 10),
itemBuilder: (ctx, index) => ClipRRect(
child: CustomPaint(
painter: OrangePainter(),
child: Container(
padding: const EdgeInsets.symmetric(horizontal:10,vertical:15),//increase padding to your liking
width: 350,
decoration: BoxDecoration(
// image: DecorationImage(image: AssetImage('')), add your image here and remove color below
color: Colors.black54,
borderRadius: BorderRadius.circular(10),
),
child: Column(
mainAxisAlignment:MainAxisAlignment.spaceBetween,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: const [
Icon(Icons.favorite, size: 40),
],
),
Row(
children: [
const Icon(Icons.restaurant),
const SizedBox(width:10),
Column(
children: const [
Text(
'Sollicitudin',
// textScaleFactor: textScale,
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 20,
shadows: [
Shadow(
color: Colors.red,
blurRadius: 10,
offset: Offset(0, 2))
],
),
),
Icon(Icons.star),//Replace with your CustomRation()
],
),
],
),
],
),
),
),
),
),
),
);
}
}
class OrangePainter extends CustomPainter {
OrangePainter();
#override
void paint(Canvas canvas, Size size) {
final rrectBorder =
RRect.fromRectAndRadius(Offset.zero & size, const Radius.circular(12));
final rrectShadow =
RRect.fromRectAndRadius(const Offset(0, 2) & size, const Radius.circular(12));
final shadowPaint = Paint()
..color = Colors.lightGreen
..style = PaintingStyle.stroke
..strokeWidth = 3
..maskFilter = MaskFilter.blur(BlurStyle.solid, 20);
canvas.drawRRect(rrectShadow, shadowPaint);
}
#override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
return true;
}
}
I am trying to make a triangle from a custom painter have a rounded corner.
Image on the left is what I have so far and Image on the right is what I am tring to do.
Here's is my code.
class Triangle extends StatelessWidget {
const Triangle({
Key? key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return CustomPaint(
painter: MyPainter(),
child: Container(
height: MySize.yMargin(10),
width: MySize.xMargin(20),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(30)),
child: Center(
child: Padding(
padding: const EdgeInsets.only(left: 30.0, bottom: 16),
child: Transform.rotate(
angle: math.pi / 4,
child: Text('New',
style: TextStyle(
color: Colors.white,
fontSize: MySize.textSize(5),
fontWeight: FontWeight.bold,
)))))));
}
}
class MyPainter extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
final paint = Paint();
paint.color = Colors.yellow;
var path = Path();
path.lineTo(size.width, 0);
path.lineTo(size.height, size.width);
path.close();
canvas.drawPath(path, paint);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
You can try to check out this package
try this:
import 'package:vector_math/vector_math.dart' as vector;
child: Container(
color: Colors.yellow,
width: 300,
height: 100,
child: Stack(
children: [
Positioned(
top: -20,
right: -20,
child: Transform.rotate(
angle: vector.radians(45),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(10)),
child: Container(
alignment: Alignment.bottomCenter,
height: 50,
width: 50,
color: Color(0xff2DD485),
child: Text('NEW'),
),
),
),
),
],
),
),
Hello Guys I would like to ask is it possible to achieve this kind of design using code? I really got stuck, here is design I would like to achieve
but the real problem is I only achieve this
this is my sample code:
in my main:
return Scaffold(
backgroundColor: Color(0xff012a60),
body: Stack(children: <Widget>[
/*_AnimatedCircle(
outerController: outerController,
innerController: innerController,
),*/
_OuterCircle(circleColor: Colors.blueGrey[900].withOpacity(.8)),
Column(children: <Widget>[
const Spacer(flex: 50),
Expanded(flex: 30, child: Container(color: Colors.white)),
const Spacer(flex: 20),
]),
Row(children: <Widget>[
const Spacer(flex: 80),
Transform.scale(
scale: 2.5,
child: Container(
width: MediaQuery.of(context).size.width * 0.2,
decoration: const BoxDecoration(
color: Colors.red, shape: BoxShape.circle)),
),
]),
// _OuterCircle(circleColor: Colors.blueAccent.withOpacity(.25)),
Row(children: <Widget>[
const Spacer(flex: 80),
Column(children: [
Spacer(flex: 60),
Transform.scale(
scale: 2.5,
child: Container(
width: MediaQuery.of(context).size.width * 0.2,
height: MediaQuery.of(context).size.width * 0.05,
decoration: const BoxDecoration(color: Colors.green)),
),
Spacer(flex: 24),
]),
]),
]),
);
and this is my other class
class _OuterCircle extends StatelessWidget {
const _OuterCircle({Key key, this.circleColor}) : super(key: key);
final Color circleColor;
#override
Widget build(BuildContext context) {
return Transform.scale(
scale: 2,
child: Container(
width: MediaQuery.of(context).size.width * 0.47,
decoration: BoxDecoration(shape: BoxShape.circle, color: circleColor),
));
}
}
Please help I really stuck how to achieve this kind of design in dart code
I think it is easier to break down the geometry problem from the largest area to small area.
The key point of achieve this is using Clip (ClipOval, ClipRect...)
The upper part can be draw by using right circle to clip left circle
The lower part can be draw by using right circle to clip inner rectangle
Scale the stack area
Draw large left circle (area 1)
Draw middle white rectangle (area 2)
Draw right circle with rectangle inside (area 3)
Draw the middle intersection part (area 4)
Widgets in used: ClipOval, FractionallySizedBox, AspectRatio,
The left Big Circle
class BigCircle extends StatelessWidget {
const BigCircle({this.color,Key key}):super(key: key);
final Color color;
#override
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: 1,
child: Container(
decoration: BoxDecoration(
color: color,
shape: BoxShape.circle,
),
),
);
}
}
The custom oval clipper (clip right white circle area)
class CustomClipOval extends CustomClipper<Rect> {
#override
Rect getClip(Size size) {
final width = size.width * 0.42;
return Rect.fromLTRB(
size.width - width,
(size.height - width) * 0.5,
size.width,
(size.height + width) * 0.5,
);
}
#override
bool shouldReclip(covariant CustomClipper<Rect> oldClipper) {
return false;
}
}
Finally the stack
return Scaffold(
backgroundColor: const Color(0xff004471),
body: Transform.scale(
scale: 1.19,
child: Stack(children: <Widget>[
// Area 1
const Align(
alignment: Alignment.centerLeft,
child: BigCircle(
color: Color(0xff022c66),
),
),
// Area 2
Align(
alignment: const Alignment(0, 0.4),
child: FractionallySizedBox(
heightFactor: 0.23,
child: Container(
color: Colors.white,
),
),
),
// Area 3
ClipOval(
clipper: CustomClipOval(),
child: Container(
alignment: const Alignment(0, 0.46),
color: Colors.white,
child: FractionallySizedBox(
heightFactor: 0.14,
child: Container(
color: const Color(0xff335f86),
),
),
),
),
// Area 4
ClipOval(
clipper: CustomClipOval(),
child: const Align(
alignment: Alignment.centerLeft,
child: BigCircle(color: Color(0xff647294),),
),
),
]),
),
);
I want to create a drop down menu like the image below, Which is opened by touching and dragging and closing by touching the outside.
before dragging
after dragging
Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false
),
body: Stack(
children: <Widget>[
Container(
height: 200,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(bottom: Radius.circular(20))
),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Align(
alignment: Alignment.bottomCenter,
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(horizontal: 40),
child: Divider(
color: Colors.blueGrey[500],
height: 10,
indent: 5,
),
),
Icon(FontAwesomeIcons.angleDoubleDown,size: 15,color: Colors.blueGrey[500],)
],
),
)
],
),
),
Center(child: Text('List View'),)
],
)
)
I want to change the height, but I encounter overflow error!
What is the best way to make this widget?
Can I do this within the AppBar?
You can do this in some ways, but one that came up in mind immediately was to use a CustomPaint widget with your own CustomPainter at the top of a Stack so you can actually keep your other widgets below the scrolled bar.
I've tried to replicate what you've shown on the images but feel free to tweak it to your needs.
const kMinScrollBarHeight = 20.0;
class MyScreen extends StatefulWidget {
_MyScreenState createState() => _MyScreenState();
}
class _MyScreenState extends State<MyScreen> {
double _scrollBarOffset = 0.0;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color.fromRGBO(13, 23, 35, 1.0),
appBar: AppBar(
backgroundColor: const Color.fromRGBO(255, 72, 18, 1.0),
),
body: Stack(children: <Widget>[
GestureDetector(
onVerticalDragUpdate: (tapDetails) => setState(() => _scrollBarOffset = tapDetails.globalPosition.dy),
child: Stack(
children: <Widget>[
Center(
child: Text(
'My screen widgets',
style: TextStyle(color: Colors.white),
),
),
Stack(
children: <Widget>[
Positioned(
bottom: MediaQuery.of(context).size.height -
max(_scrollBarOffset,
MediaQuery.of(context).padding.top + kToolbarHeight + kMinScrollBarHeight),
child: CustomPaint(
painter: MyDraggable(),
child: Container(
height: MediaQuery.of(context).size.height,
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FlutterLogo(
size: 100.0,
),
Text('Flutter is awesome'),
],
),
),
),
),
],
),
],
),
),
]),
);
}
}
class MyDraggable extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
final Paint paint = Paint()..color = Colors.white;
final Radius cornerRadius = Radius.circular(20.0);
final double lineMargin = 30.0;
// Draw slider
canvas.drawRRect(
RRect.fromLTRBAndCorners(0.0, 0.0, size.width, size.height,
bottomLeft: cornerRadius, bottomRight: cornerRadius),
paint);
paint.color = Colors.black.withAlpha(64);
paint.strokeWidth = 1.5;
// Draw triangle
canvas.drawPoints(
PointMode.polygon,
[
Offset((size.width / 2) - 5.0, size.height - 10.0),
Offset((size.width / 2) + 5.0, size.height - 10.0),
Offset((size.width / 2), size.height - 5.0),
Offset((size.width / 2) - 5.0, size.height - 10.0),
],
paint);
// Draw line
canvas.drawLine(Offset(lineMargin, size.height - kMinScrollBarHeight),
Offset(size.width - lineMargin, size.height - kMinScrollBarHeight), paint);
}
#override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}