Flutter. How to draw these designs in a container - flutter

enter image description here
Please tell me how to draw these encircled geometrical lines in a container .
After drawing a container widget how should i draw these custom geometrical designs in a container

class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Square'),
),
body: Center(
child: Column(
children: [
SquarePercentIndicator(
width: 140,
height: 140,
startAngle: StartAngle.bottomRight,
reverse: true,
borderRadius: 10,
shadowWidth: 1.5,
progressWidth: 5,
shadowColor: Colors.grey,
),
],
),
)
);
}
}

I suggest you to use figma to style these types of lines and shapes, and export it as png image.
If you want to code the entire drawing, it is not recommend, but it can be achieved, using rounded bordered containers, but there would be lot of limitations

Related

Container inside ListView will expand even though it has height

The following Container inside a ListView, won't have a height, even though I specified one. Instead it expands to the entire ListView's height
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
MyHomePage({Key? key, required this.title}) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ListView(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
children: [
Container(
width: 100,
height: 20,
color: Colors.red)
])
);
}
}
According to https://api.flutter.dev/flutter/widgets/Container-class.html,
If the widget has no child and no alignment, but a height, width, or
constraints are provided, then the Container tries to be as small as
possible given the combination of those constraints and the parent's
constraints.
so shouldn't the Container be as small as possible, since it has constraints?
Have a look at Understanding Constraints in Flutter Docs.
The constraints given by the ListView to its children is too exactly fill the cross axis. Your Container cannot decide to have a size out of these constraints.
Remember, constraints go down, sizes go up.
You should position your Containers inside the ListView. In the following example, the first Container (Red) is not positioned, the second (Green) is Centered and the last (Blue) is Aligned on topLeft:
Center andAlign widgets both will take maximum height and give flexibility to their child, your Container.
Full source code:
import 'dart:math' show Random;
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
MyHomePage({Key? key, required this.title}) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Colors.grey.shade200,
child: ListView(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
children: [
Container(width: 100, height: 20, color: Colors.red),
Center(
child: Container(width: 100, height: 10, color: Colors.green),
),
Align(
alignment: Alignment.topLeft,
child: Container(width: 100, height: 20, color: Colors.blue),
),
],
),
),
);
}
}
Try to wrap the ListView with a Container with a fixed height.
The ListView will take up all available space unless constrained, constraining the height of the ListView would fix the issue. You can wrap the ListView in a container with certain height (20, in your case).

Flutter converting MainAxisSize.max to float

So I'm building a flutter app, a screen contains a column with four containers. I haven't specified the containers heights as I want them to take up the whole screen. Is there a way to convert the mainAxisSize to a float so that I can set the height of the containers to a quarter of the axis size. Thanks
For the containers you can use the attribute heigth. Then, you can use
screenHeigth=MediaQuery.of(context).size.heigth to obtain the heigth size of the phone you are using. Last of all, you can set the Containes' heigth attribute to: screenHeigth*0.25
So, each of them are 1/4 of the screen size high!
Here's the quick solution I think you are looking for. If not, let me know what to achieve other than this:
Demo:
**Code: **
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
#override
Widget build(BuildContext context) {
// Getting Quarter Height of the screen
double qtrScreen = MediaQuery.of(context).size.height * 0.25;
return Scaffold(
body: Column(
children: [
Container(
color: Colors.red,
height:
qtrScreen, // Providing the Quarter height to all Containers
),
Container(
color: Colors.green,
height: qtrScreen,
),
Container(
color: Colors.blue,
height: qtrScreen,
),
Container(
color: Colors.orange,
height: qtrScreen,
),
],
),
);
}
}
You can use expanded and define flex property as you need. You don't need to create values using media query as it makes the code more complex for beginners.

How to expand this lottie animation to fill the whole screen - Flutter

I am currently working on having a gradient background animation in my app... I am doing so with the help of a lottie animation! I have tried to enclose it in a container and have succeeded in doing so. However there is one issue, I am not able to make the container bigger than a certain amount despite me changing the height to something even bigger than 2000... I really dont know what to do to make sure that there are no whitespaces in the screen and that this gradient fills the screen in all devices. Here is the code. I have also added in a screenshot of how it looks so that you get an idea of whats happening.
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
class WelcomeScreen extends StatefulWidget {
#override
_WelcomeScreenState createState() => _WelcomeScreenState();
}
class _WelcomeScreenState extends State<WelcomeScreen> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Padding(
padding: const EdgeInsets.all(0),
child: Container(
height: 1000,
width: 1000,
child: Lottie.asset('assets/gradient-background.json'),
),
),
));
}
}
I am new to flutter development so please forgive me if this is a very silly mistake! Thanks a lot and i really appreciate your help!
First of all, i would like to thank you all for your help. Special thanks to Nehal because he made me aware about the fit property which turns out to be a feature of a lottie asset animation! Thanks so much and this is the correct code:
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
class WelcomeScreen extends StatefulWidget {
#override
_WelcomeScreenState createState() => _WelcomeScreenState();
}
class _WelcomeScreenState extends State<WelcomeScreen> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
height: double.infinity,
width: double.infinity,
child:
Lottie.asset('assets/gradient-background.json', fit: BoxFit.cover),
),
));
}
}
I was able to fix this by using OverflowBox.
SizedBox(
height: 120,
child: OverflowBox(
minHeight: 170,
maxHeight: 170,
child: Lottie.asset(
'assets/file.json',
repeat: false,
),
),
)
Use an expanded widget and dont use any padding. You dont need to mention the height or width of the container and use the background property in decoration of container
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
class WelcomeScreen extends StatefulWidget {
#override
_WelcomeScreenState createState() => _WelcomeScreenState();
}
class _WelcomeScreenState extends State<WelcomeScreen> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Expanded(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/gradient-background.json'),
fit: BoxFit.cover,
),
),
),
),
),
);
}
}
Also you can make a custom gradient in flutter rather than using a background photo.

Masked Blur for Image

I would like to implement the effect shown below in which most parts of an image are blurred and only the interesting part of the image is shown crisp (with a border).
I am not sure how to implement the effect and would like to consider your ideas. Blurring the image is not the problem (i am doing it as described here), but leaving a part of the image non-blurred is quite a challenge. I thought about layering two images (one blurred and one non-blurred) over each other. However that will not work because then the blurred image will cast a shadow over the cutout section.
I also tried to use a CustomPainter, however i failed to get the blur working.
This is how you can do it , The idea is to make CustomClipper to invert the behavior of the BackDropFilter.
import 'dart:ui';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.green,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SizedBox(
height: 250,
child: Stack(
children: <Widget>[
Center(
child: Image.network(
'https://cdn-prod.medicalnewstoday.com/content/images/articles/322/322736/elephant-from-the-front.jpg')),
Center(
child: ClipPath(
clipper: InvertedRect(),
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
child: Container(
color: Colors.transparent,
),
),
),
),
],
),
),
);
}
}
class InvertedRect extends CustomClipper<Path> {
#override
getClip(Size size) {
print(size);
return Path()
..addRect(Rect.fromLTWH(0.0, 0.0, size.width, size.height))
..addRect(Rect.fromLTWH(100.0, 40.0, 100, 100))
..fillType = PathFillType.evenOdd;
}
#override
bool shouldReclip(CustomClipper<Path> oldClipper) => true;
}

Flutter: make container occupy other container size within a Stack

I have a flutter app in which I have a stack and within a Container with some elements. I want to give some gesture detection and show an overlay layer when the user clicks on it. I have think of creating another container with the color and shape I want and then make it occupy the same space of the other container but above it.
The problem is that I can't figure out how to make the overlay container to have the same size than the main container.
This is what I have basically:
import 'package:flutter/material.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: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _layerVisible = false;
#override
Widget build(BuildContext context) {
List<Widget> array = List();
array.add(Stack(
children: <Widget>[
GestureDetector(
onTapDown: (TapDownDetails details) {
setState(() {
_layerVisible = true;
});
},
onTapUp: (TapUpDetails details) {
setState(() {
_layerVisible = false;
});
},
child: Container(
padding: EdgeInsets.all(8),
color: Colors.yellow,
child: Column(
children: <Widget>[
Padding(
child: Text("Title text"),
padding: EdgeInsets.only(bottom: 10),
),
Text(
"Veeery long text. This is a dynamic value so we don't really know how long it's going to be...this means that the parent container is going to grow.")
],
)),
),
Visibility(
visible: _layerVisible,
child: Container(
color: Colors.grey,
child: Text(
"This is the container that I want to fit exactly in the yellow container."),
),
)
],
));
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
width: 300,
child: ListView(
children: array,
),
));
}
}
What I want is to make the last container within the stack to occupy the same space of the other container, this way I can create an overlay layer when I click on it.
I try using Expanded, using Positioned.fill, but none of this solution works for me.
Thanks.
Try using an IntrinsicHeight above your Stack. It'll give an explicit size based off the largest widget in the stack to the Stack itself. Then, make sure you add a fit: StackFit.passthrough, on the Stack. That'll pass down the sizing information from IntrinsicHeight to all of it's children.