Issue
I am trying to build a website using flutter and I want it’s background to have a wavy corner with a different color at one end. I need four blocks in this designs i.e. as you scroll you’ll reveal new blocks, and the height of each block should be the same as the height of the screen.
So, I thought of using CustomPaint to do it so I started to implement it but I am getting around 500 lines of error messages and it’s not working.
I’m new to flutter so I don’t know if I’ve implemented everything the way it should be implemented. I’ve shared all the code down below:
main.dart
import 'package:flutter/material.dart';
import 'blocks/block1.dart';
import 'blocks/block2.dart';
import 'blocks/block3.dart';
import 'blocks/block4.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Home(),
);
}
}
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: <Widget>[
BlockOne(),
//BlockTwo(),
//BlockThree(),
//BlockFour()
],
),
)
);
}
}
block1.dart – block 2, 3 and 4 are almost similar:
Note- I’ve not added the wavy pattern in this code below because this itself is not working
import 'package:flutter/material.dart';
class BlockOne extends StatefulWidget {
@override
_BlockOneState createState() => _BlockOneState();
}
class _BlockOneState extends State<BlockOne> {
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
if (constraints.maxWidth > 1024)
return Desktop();
else
return Mobile();
},
);
}
}
class Desktop extends StatefulWidget {
@override
_DesktopState createState() => _DesktopState();
}
class _DesktopState extends State<Desktop> {
@override
Widget build(BuildContext context) {
return Container(
child: Text('Desktop'),
);
}
}
class Mobile extends StatefulWidget {
@override
_MobileState createState() => _MobileState();
}
class _MobileState extends State<Mobile> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomPaint(
size: const Size(double.infinity, double.infinity),
painter: MobilePainter(),
),
);
}
}
class MobilePainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final height = size.height;
final width = size.width;
Paint paint = Paint();
paint.color = Colors.black;
Path background = Path();
background.addRect(Rect.fromLTRB(0, 0, width, height));
canvas.drawPath(background, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return oldDelegate != this;
}
}
Solution
Check the following. Here I am using a list view to show contents. In flutter it is important to understand the concept that constraints go down from parent to child and the size goes up from a child to parent.
Here is demo of how this can be achieved. dartpad demo
If the child doesn’t define a size then in ListView
you have to define the itemExtent
.
import 'package:flutter/material.dart';
// import 'blocks/block1.dart';
// import 'blocks/block2.dart';
// import 'blocks/block3.dart';
// import 'blocks/block4.dart';
void main() {
runApp(ScrollableView());
}
class ScrollableView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Home(),
);
}
}
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
// child: Column(
shrinkWrap: true,
itemExtent: 200,
children: <Widget>[
BlockOne(),
Container(
color: Colors.black,
),
BlockOne(),
Text('Hello'),
BlockOne(),
Container(
color: Colors.black,
),
BlockOne(),
//BlockTwo(),
//BlockThree(),
//BlockFour()
],
// ),
));
}
}
class BlockOne extends StatefulWidget {
@override
_BlockOneState createState() => _BlockOneState();
}
class _BlockOneState extends State<BlockOne> {
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
// if (constraints.maxWidth > 1024)
// return Desktop();
// else
return Mobile();
},
);
}
}
class Desktop extends StatefulWidget {
@override
_DesktopState createState() => _DesktopState();
}
class _DesktopState extends State<Desktop> {
@override
Widget build(BuildContext context) {
return Container(
child: Text('Desktop'),
);
}
}
class Mobile extends StatefulWidget {
@override
_MobileState createState() => _MobileState();
}
class _MobileState extends State<Mobile> {
@override
Widget build(BuildContext context) {
return CustomPaint(
size: const Size(double.infinity, double.infinity),
painter: MobilePainter(),
);
}
}
class MobilePainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final height = size.height;
final width = size.width;
Paint paint = Paint();
paint.color = Colors.green;
Path background = Path();
background.addRect(Rect.fromLTRB(0, 0, width, height));
canvas.drawPath(background, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return oldDelegate != this;
}
}
Answered By – Abhilash Chandran
Answer Checked By – David Goodson (FlutterFixes Volunteer)