How to get an image above background while shadowing background in flutter - flutter

I have an image and I want it to appear on my screen, above my background, with keeping background a bit dark type like in the image. I am thinking on using AlertDialog to display the image, but if you think there is a better way of doing it or a specific widget for this, please do tell me. Also please tell me what do we name this kind of image which hovers over background and focusing itself in UI.
enter code here
Just for trying out, I used this in my screen's initstate, as I want it to appear as soon as my screen appears -
super.initState();
showDialog(
context: context,
builder: (BuildContext buildContext) {
return AlertDialog(
content: Center(
child: Container(
color: Colors.red,
width: 200,
height: 200,
),
),
);
}
);

initState doesn't contain context you can get context after first frame.
You can use addPostFrameCallback
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
showDialog(..);}
Or Future.delayed
Future.delayed(Duration.zero).then((value) {
showDialog(..); }
The dialog construction is :
showDialog(
context: context,
builder: (BuildContext buildContext) {
const double iconSize = 48;
return LayoutBuilder(
builder: (context, constraints) => AlertDialog(
backgroundColor: Colors.transparent,
elevation: 0,
contentPadding: EdgeInsets.zero,
content: SizedBox(
width: constraints.maxWidth * .75,
height: constraints.maxHeight * .75,
child: Stack(
children: [
///background image with fit Cover
Align(
alignment: Alignment.center,
child: Container(
width: constraints.maxWidth * .75 - iconSize,
height: constraints.maxHeight * .75 - iconSize,
color: Colors.cyanAccent,
),
),
Align(
alignment: Alignment.topRight,
child: GestureDetector(
onTap: () {
Navigator.of(context).pop();
},
child: Container(
decoration: const BoxDecoration(
color: Colors.white, shape: BoxShape.circle),
child: const Icon(
Icons.close,
size: iconSize,
),
),
),
)
],
),
),
),
);
},
);

You can use Stack widget withe three widget as children.
first children widget is your background screen.
second children widget is a Container widget with color .withOpacity().
third children widget is the image you are trying to show on top.
Like this:
return Scaffold(
body: Stack(
children: [
Container(
color: Colors.white,
),
Container(
color: Colors.black.withOpacity(0.5),
),
Center(
child: Container(
height: MediaQuery.of(context).size.height * 70 / 100,
width: MediaQuery.of(context).size.width * 80 / 100,
color: Colors.purple,
),
),
],
),
);
for Visibility issue you can use this.
bool isVisible = false;
#override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: Stack(
children: [
Container(
color: Colors.red,
child: Center(
child: Container(
child: TextButton(
onPressed: () {
setState(() {
isVisible = true;
});
},
child: Text('Show Widget'),
),
),
),
),
Visibility(
visible: isVisible,
child: GestureDetector(
onTap: () {
setState(() {
isVisible = false;
});
},
child: Container(
color: Colors.white.withOpacity(0.5),
),
),
),
Visibility(
visible: isVisible,
child: Center(
child: Container(
height: MediaQuery.of(context).size.height * 70 / 100,
width: MediaQuery.of(context).size.width * 80 / 100,
color: Colors.purple,
child: Stack(
children: [
Positioned(
top: 0.0,
right: 0.0,
child: IconButton(
icon: const Icon(
Icons.close,
color: Colors.white,
),
onPressed: () {
setState(() {
isVisible = false;
});
},
),
),
],
),
),
),
),
],
),
);
}

Related

button shadow when clicked is covered by other widget

Button's shadow is happened when click the button.
But, the shadow is covered by other widget.
How can I resolve this?
#override
Widget build(BuildContext context) {
int total = 0;
for (int i = 1; i <= count; i++) {
total += i;
}
return Stack(
clipBehavior: Clip.none,
children: [
Container(
width: 343.43,
height: 150.62,
decoration: RadiusAndShadow().getDecoration(),
child: Column(
children: <Widget>[
Header(text: name),
EcRow(t1: '칼로리', t2: '1회당 ${calorie}kcal'),
EcRow(t1: '카드개수', t2: '$count 개'),
EcRow(t1: '반복횟수', t2: '$total회'),
],
),
),
Positioned(
width: 343.43,
height: 150.62,
top: 17,
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 40,
width: 40,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.black,
),
child: IconButton(
padding: const EdgeInsets.all(0),
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return ExEdit();
}));
},
icon: const Icon(
Icons.edit_outlined,
color: Colors.white,
size: 30,
),
),
),
),
),
],
);
}
I used Stack widget.
In Stack, there are Container and Positioned.
In Container, there are Header and Text.
In Positioned, there is an IconButton.
I didn't understand exactly what happens since you did not provide any code, but I think when you click on the IconButton a splash effect happens and not exactly a shadow so inside the IconButton add:
splashRadius: 20,
you can also disable this effect:
return Theme(
data: ThemeData.light().copyWith(
textTheme: GoogleFonts.poppinsTextTheme(),
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
),
child: const WelcomeScreen(),
);
Wrap your IconButton with widget Material
in Material
color: Colors.transparent,
in IconButton
splashRadius: 20,

Flutter: How do I show an AlertBox as soon as my network image is loaded and only for once after app opens

I am trying to show an image on my screen, in an AlertBox. I am fetching the image from the network and then displaying it in the UI. I have a variable announcementImage, which is fetching data from API and stores the url in the variable. I want, as soon as I receive the image URL and as soon as the image loads, my AlertBox should appear. And this should happen only once, i.e. after the app starts. It should not appear again after I come back from another page.
Here is the code of initState -
#override
void initState() {
super.initState();
print("\n \n \n \n Started initialize \n \n");
Future.delayed(Duration.zero).then((value) {
showDialog(
context: context,
builder: (BuildContext buildContext) {
const double iconSize = 27;
return LayoutBuilder(
builder: (context, constraints) => AlertDialog(
backgroundColor: Colors.transparent,
elevation: 0,
contentPadding: EdgeInsets.zero,
content: SizedBox(
width: constraints.maxWidth * .75,
height: constraints.maxHeight * .71,
child: Stack(
children: [
Align(
alignment: Alignment.center,
child: ValueListenableBuilder(
valueListenable: announcementImage,
builder: (BuildContext context, String? url, Widget? child) {
return Image.network(
url??"",
width: constraints.maxWidth * .72 - iconSize,
height: constraints.maxHeight * .72 - iconSize,
);
},
),
),
Align(
alignment: Alignment.topRight,
child: GestureDetector(
onTap: () {
Navigator.of(context).pop();
},
child: Container(
decoration: const BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
child: Padding(
padding: const EdgeInsets.all(7.0),
child: const Icon(
Icons.close,
size: iconSize,
color: colorPrimary,
),
),
),
),
)
],
),
),
),
);
},
);
});
}

Error: The getter 'context' isn't defined for the class 'MyApp'

I want to make an app that contain 4 buttons and it will go to other page if I click the button. But when I use the navigator it shows an error at context.
import 'package:flutter/material.dart';
import 'package:mytestapp/LectureVideo.dart';
import 'package:path/path.dart';
void main() {
runApp( MaterialApp(
debugShowCheckedModeBanner: false, //hide debug sash at top right
title: 'HomePage',
home: MyApp(),
)
);
}
class MyApp extends StatelessWidget{
#override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width; //getting screen width
return Scaffold(
appBar: AppBar(title: Text('Welcome to EMTeach'),
centerTitle: true,
backgroundColor: Colors.lime[200],
),
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(margin: EdgeInsets.only(bottom: 20.0)),
FirstButton(width),
Container(margin: EdgeInsets.only(bottom: 20.0)),
SecondButton(width),
Container(margin: EdgeInsets.only(bottom: 20.0)),
ThirdButton(width),
Container(margin: EdgeInsets.only(bottom: 20.0)),
FourthButton(width),
Container(margin: EdgeInsets.only(bottom: 20.0)),
],
),
),
);
}
Widget FirstButton(double width) {
return Expanded(
child: SizedBox(
width: width - 20,
child: RaisedButton(
onPressed: () {
Navigator.push(
context, //error
MaterialPageRoute(builder: (context) => LectureVideo()));
},
color: Colors.red,
child: Text(
"Lecture Video",
textScaleFactor: 2.0,
),
),
//fit: BoxFit.cover,
),
);
}
Widget SecondButton(double width) {
return Expanded(
child: SizedBox(
width: width - 20,
child: RaisedButton(
onPressed: () {},
color: Colors.lightGreen,
child: Text(
"Application Video",
textScaleFactor: 2.0,
),
),
//fit: BoxFit.cover,
),
);
}
Widget ThirdButton(double width) {
return Expanded(
child: SizedBox(
width: width - 20,
child: RaisedButton(
onPressed: () {},
color: Colors.lightBlue,
child: Text(
"List of Equation",
textScaleFactor: 2.0,
),
),
//fit: BoxFit.cover,
),
);
}
Widget FourthButton(double width) {
return Expanded(
child: SizedBox(
width: width - 20,
child: RaisedButton(
onPressed: () {},
color: Colors.orange,
child: Text(
"List of Question",
textScaleFactor: 2.0,
),
),
//fit: BoxFit.cover,
),
);
}
}
the problem is you are not passing the context which is the parameter of the build function over to your buttons try this:
Widget FirstButton(double width,BuildContext context ) {
return Expanded(
child: SizedBox(
width: width - 20,
child: RaisedButton(
onPressed: () {
Navigator.push(
context, //error
MaterialPageRoute(builder: (context) => LectureVideo()));
},
color: Colors.red,
child: Text(
"Lecture Video",
textScaleFactor: 2.0,
),
),
//fit: BoxFit.cover,
),
);
}

Flutter: Use appBar Widget in Floating Action Button instead of the appBar?

Here's the widget I'm using in the appBar;
appBar: AppBar(actions: <Widget>[myAppBarIcon()],)
And the code for the widget itself;
Widget myAppBarIcon() {
return ValueListenableBuilder(
builder: (BuildContext context, int newNotificationCounterValue,
Widget child) {
return newNotificationCounterValue == 0? Container(): Stack(
children: [
Icon(
Icons.notifications,
color: Colors.white,
size: 30,
),
Container(
width: 30,
height: 30,
child: Container(
width: 15,
height: 15,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Color(0xffc32c37),
border: Border.all(color: Colors.white, width: 1)),
child: Padding(
padding: const EdgeInsets.all(0.0),
child: Text(
newNotificationCounterValue.toString(),
),
),
),
),
],
);
},
valueListenable: notificationCounterValueNotifer,
);
}
But I would now like to use the widget in a floating action button instead of the appBar. So here's what I tried;
Scaffold(
body: FoldableSidebarBuilder(
drawerBackgroundColor: Colors.black45,
drawer: CustomDrawer(closeDrawer: (){
setState(() {
drawerStatus = FSBStatus.FSB_CLOSE;
});
},),
screenContents: mainStage(),
status: drawerStatus,
),
floatingActionButton: Stack(
children: <Widget>[
Positioned(
bottom:140,
left: 17,
child: FloatingActionButton(
mini: true,
heroTag: null,
backgroundColor: Colors.black12,
child: myAppBarIcon()
),
),
],
),
),
But although no error comes up, myAppBarIcon isn't appearing in the build. Where did I go wrong?
Turns out it does work. I didn't think so at first till I realized I needed to receive an FCM notification before it appeared. This line was the reason.;
return newNotificationCounterValue == 0? Container()
So I'm going to put an empty notification icon in the container.

How to layer text over column widgets in flutter?

edit:
I made "I AM" bright neon green, but its mixing with the button colors to a dark green.
I want to display text over two buttons that cover the whole screen, 1 top half and 1 bottom half. I want text to display in the middle of the screen, kind of covering part of each button.
This is my code for the buttons:
Widget build(BuildContext context) {
return Scaffold(
body: Align(
alignment: Alignment.center,
child: Column(
children: <Widget>[
Container(
height: (MediaQuery.of(context).size.height) / 2,
width: MediaQuery.of(context).size.width,
child: RaisedButton(
color: Colors.black87,
child: poorText,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
},
),
),
Container(
height: (MediaQuery.of(context).size.height) / 2,
width: MediaQuery.of(context).size.width,
child: RaisedButton(
color: Colors.black87,
child: richText,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ThirdRoute()),
);
},
),
),
],
),
),
);}
I have tried to use stack, but it says too many positional arguments are being used. How would I keep my column layout and layer text over the buttons? If there is another way without column that still allows makes the buttons work that's fine too. Thanks!
You can use a Stack widget to achieve that:
Note. Because the two buttons are aligned to the center, you have to align the text widget also to the center so it can be placed directly ob=ver the two button.
Check the code below:
It works perfectly:
Widget build(BuildContext context) {
return Scaffold(
// use a stack widget
body: Stack(
children: [
// text to display over buttons
Align(
// set alignment to center to place it over the buttons
alignment: Alignment.center,
child: Text(
'Text you want to display over the buttons',
// give it your style
style: TextStyle(
),
),
),
Align(
alignment: Alignment.center,
child: Column(
children: <Widget>[
Container(
height: (MediaQuery.of(context).size.height) / 2,
width: MediaQuery.of(context).size.width,
child: RaisedButton(
color: Colors.black87,
child: poorText,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
},
),
),
Container(
height: (MediaQuery.of(context).size.height) / 2,
width: MediaQuery.of(context).size.width,
child: RaisedButton(
color: Colors.black87,
child: richText,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ThirdRoute()),
);
},
),
),
],
),
),
],
),
);}
I hope this helps.
Use 2 Columns widget within a Stack widget. The code below achieves exactly what you want if I understood you well.
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Column(
children: <Widget>[
Container(
height: (MediaQuery.of(context).size.height) / 2,
width: MediaQuery.of(context).size.width,
child: RaisedButton(
color: Colors.blue,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
},
),
),
Container(
height: (MediaQuery.of(context).size.height) / 2,
width: MediaQuery.of(context).size.width,
child: RaisedButton(
color: Colors.red,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ThirdRoute()),
);
},
),
),
],
),
Column(
children: <Widget>[
Container(
// set alignment to center to place it over the buttons
height: (MediaQuery.of(context).size.height) / 2,
width: MediaQuery.of(context).size.width,
child: Center(child: Text('Text 1')),
),
Container(
// set alignment to center to place it over the buttons
height: (MediaQuery.of(context).size.height) / 2,
width: MediaQuery.of(context).size.width,
child: Center(child: Text('Text 2')),
),
],
)
],
);
}