Flutter clippath over appbar - flutter

Hi Im having problem with clippath, Im trying to do a clippath like in the inserted image link [https://imgur.com/qDspPgV]. However, I realised I cant actually do this in flutter because appbar is block the way so it gives me a white space.
Is there a way where I could overlap it?
This is my code
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle(statusBarColor: Colors.transparent));
runApp(LoginUI());
}
class LoginUI extends StatefulWidget {
#override
_LoginUIState createState() => _LoginUIState();
}
class _LoginUIState extends State<LoginUI> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Login"),
),
body: SafeArea(child: Builder(builder: (BuildContext context) {
return Container(
color: Colors.white,
child: ClipPath(
clipper: MyClipper(),
child: Container(
color: Colors.red,
)));
})),
));
}
}
class MyClipper extends CustomClipper<Path> {
#override
Path getClip(Size size) {
Path path = new Path();
path.lineTo(0, size.height * .5);
path.lineTo(size.width, 0);
return path;
}
#override
bool shouldReclip(CustomClipper<Path> oldClipper) {
return true;
}
}
This is my design output because of appbar
[https://imgur.com/UaKFvBO]
the clippath on the design is a placeholder. I havent decided to change it yet until I actually manage to overlap the appbar.
Edit: suggestion upon without appbar [https://imgur.com/93O1kX7], it doesnt go thoroughly on the status bar.
Edit: Thanks Albert [ https://imgur.com/5QsztCr ].

You can achieve what you want just by omitting the appBar Scaffold parameter and passing this clipped container at the top of a Column that you would have in your Scaffold's body.
Also remember that SafeArea paddings out from the status bar among other things.

Related

Is MaterialApp/Scaffold absorb my Listener?

I try to code a very simple Whiteboard. When I use
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
child: Listener(
the app isn't recognizing any mouseclick (onPointerDown()). When I use directly
Widget build(BuildContext context) {
return Container(
child: Listener(
everything is ok and I can see some action in the onPointerDown(). So, I think I miss something. I want to use the MaterialApp, to get access to some of the features.
What I tried so far:
At first, I tried to minimize my function, to focus on only that problem.
So, this is my full minimized code:
import 'package:flutter/material.dart';
void main() {
runApp(App());
}
class App extends StatefulWidget {
#override
AppState createState() => AppState();
}
class AppState extends State<App> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Container(
color: Colors.white,
child: Listener(
onPointerDown: (details) {
print('Action');
},
child: CustomPaint(
painter: DrawingPainter(),
),
))));
}
}
class DrawingPainter extends CustomPainter {
DrawingPainter();
#override
void paint(Canvas canvas, Size size) {}
#override
bool shouldRepaint(DrawingPainter oldDelegate) => true;
}
What I recognized, the size of the DrawingPainter is (0.0, 0.0). Maybe the Problem is that the Painter isn't span about the full size? If this is so, how can I change that? I tried to set the size, but ended with size == 0.0, 0.0 again.
Yes, you just have to use a SizedBox.expand or anything that will force your content to expand its size to match parent.
see https://zu4c06ylu4d0.zapp.page/#/

Keep global ThemeData across screens

Is it possible to set ThemeData globally so you don't have to on the next screens?
Currently after I use the Navigator.pushI have to make sure the new screen Widget have instructions like Theme.of(context).backgroundColor
Is there a way for the app screens/widgets to automatically pick whatever is set in the main.dart theme?
Eg, Here is my main.dart
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(backgroundColor: Colors.red, primaryColor: Colors.green),
home: LoadingScreen(),
);
}
}
and this is the loadingscreen:
class _LoadingScreenState extends State<LoadingScreen> {
#override
void initState() {
super.initState();
getFiles();
}
void getFiles() async {
await Future.delayed(Duration(seconds: 3));
Navigator.push(context, MaterialPageRoute(builder: (context) {
return StartScreen(file: null);
}));
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Theme.of(context).backgroundColor,
child: Center(
child: Image.asset(
height: 100.0,
)),
),
);
}
}
Without a Theme.of(context).backgroundColor in the Container, the app will load a white page behind the image, instead of red as defined in the ThemeData.
Is that a way to avoid the extensive usage of Theme.of(context).backgroundColor everywhere?
When you set the Scaffolds backgroundcolor in the ThemeData every Scaffold should use that color as a backgroundcolor. On your LoadingScreen the extra Container is unecessery since it would override the Scaffolds backgroundcolor.
Refer to this answer on how to set the backgroundcolor: https://stackoverflow.com/a/55581726/13406356

Why is showModalBottomSheet covers bottomNavigationBar, while showBottomSheet displayed on top of it position-wise?

I have an application (simplified) that looks like this:
working dartpad example:
https://dartpad.dev/cc4e524315e104c272cd06aa7037aa10
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: MyWidget(),
),
bottomNavigationBar: BottomWidget(),
),
);
}
}
class MyWidget extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Text('Hello, World!');
}
}
class BottomWidget extends StatelessWidget {
Widget build(BuildContext context) {
return BottomAppBar(
child: InkWell (
child: Container(
height:100,
color: Colors.pink,
child: Center(
child: Text('this is a bottom navigation bar')
),
),
onTap: () {
showModalBottomSheet(
context: context,
builder: (context) => Container(),
);
}
),
);
}
}
My question is, I want to use showModalBottomSheet to stop user from interacting with the screen, but I need bottomNavigationBar to be shown like this:
Right now it just covers everything including the bottomNavigationBar:
If I change it to showBottomSheet, it works perfectly like the first picture.
Why is their behaviour different?
How can I achieve the result that I want using showModalBottomSheet?
showModalBottomSheet show bottom sheet on top of all widget and layers, if you want to show it under bottomNavigationBar you should use Stack in parent and use a single child into that. its not easy to take a sample and that take a long time to reproduce pseudo code

How to remove appbar grey line flutter

I was working with Flutter and saw this:
a grey line appeared on my screen.
maybe it is because the appbar is moved down by, for example, 5px and the background color is set to grey?
BTW on iPhones, it works perfect, no lines
Container(
if I delete width but uncomment height it works but it sets a width of background around 200px I need double.infiniti
If I run the code it sets width to device.width but make the grey line visible
// height: device.height * 390 / 812,
width: double.infinity,
child: BuildSvg('assets/svg/backgroundGradient.svg'),
),
buildsvg
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class BuildSvg extends StatelessWidget {
final url;
BuildSvg(this.url);
#override
Widget build(BuildContext context) {
final String assetName = url;
final Widget svg = new SvgPicture.asset(assetName, semanticsLabel: '');
return svg
}
}
I change bgckcolor to red
This might help you :
you can change the color of the status bar from scaffold so it can be transparent
import 'package:flutter/services.dart';
class WelcomeScreen extends StatefulWidget {
#override
_WelcomeScreenState createState() => _WelcomeScreenState();
}
class _WelcomeScreenState extends State<WelcomeScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
systemOverlayStyle: SystemUiOverlayStyle(statusBarColor: Colors.transparent),
elevation: 0,
backgroundColor: Colors.transparent,
),
)
}

How to fix a widget in the footer with flutter

I'd like to fix an Image in the footer of the screen, so in different phones it stays always in the bottom .
What I tried
I tried to use Column, and then in the mainAxisAlignment I would use MainAxisAlignment.end
Additional Question : Is there a way to create a canvas and place it on the image, so I can use relative coordinate on the image if I want to draw something instead of the full screen
You can use the bottomSheet in the scaffold. This automatically allows you to have the widget fixed at the bottom of the display
return Scaffold(
bottomSheet: yourWidget(),
body: Container(color: Colors.red,)
);
Please write a question for each question you have in the future - that makes them more searchable and useful in the future for other people.
However, I think I can answer both pretty simply so I will.
Firstly, if you want an image to always be at the foot of the screen, you can simply use a the bottomNavigationBar property of the Scaffold. It looks like it would have to be a BottomNavigationBar but you can actually pass any widget you'd like.
Here's the code (you can paste it into a file and run that file as it's self-enclosed):
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() => new MyAppState();
}
class MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
bottomNavigationBar: Stack(
children: [
new Container(
height: 100.0,
color: Colors.green,
),
Positioned(
left: 0.0,
right: 0.0,
top: 0.0,
bottom: 0.0,
child: new CustomPaint(
painter: Painter(),
size: Size.infinite,
),
),
],
),
),
);
}
}
class Painter extends CustomPainter {
#override
void paint(Canvas canvas, Size size) {
canvas.drawLine(Offset.zero, size.bottomRight(Offset.zero), Paint());
}
#override
bool shouldRepaint(CustomPainter oldDelegate) {
// bad, but okay for example
return true;
}
}
I've just used a simple painter to illustrate the 'canvas' and how to position it the same as the picture, and a Container with a colour instead of a picture as I don't feel like adding assets to my project. The Positioned widget makes it so that the canvas can be sized to the image and not the other way around, as would happen if you just put them right into the Stack.
Note that if you don't want to use scaffold, you could probably also do this using a Column, with whatever you want for the body wrapped in an Expanded widget (as that will make it expand to fit as much space as possible, which should be everything except the space the image takes up).
you can use persistentFooterButtons widget inside Scaffold
#override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Demo App'),
),
body: _questionIndex < _questions.length
? Quiz(
list: _questions,
selectHandler: _printAns,
questionIndex: _questionIndex)
: Result(_totalScore, _resetQuiz),
persistentFooterButtons: <Widget>[
Row(
children: <Widget>[
RaisedButton(
onPressed: null,
child: Text('Prev'),
),
RaisedButton(
onPressed: null,
child: Text('Next'),
),
],
)
],
),
);