How to overlap a widget with a custom appbar - flutter

I want to achieve an effect similar to this one:
Here's what I have: (Blue container is hidden below the appBar)
And this is my current code:
Widget build(BuildContext context) {
return Scaffold(
appBar: GradesAppBar(
title: "Grades",
gradientBegin: Colors.red[200],
gradientEnd: Colors.red,
),
body: Stack(
fit: StackFit.expand,
overflow: Overflow.visible,
children: <Widget>[
Positioned(
top: -20,
left: MediaQuery.of(context).size.width / 2 - 150,
child: Container(
color: Colors.blue,
width: 300,
height: 60,
),
),
],
),
);
}
The GradesAppBar is a Container with boxShadow, borderRadius and gradient decoration.

When you're using stack to achieve this UI approach you should remove the AppBar and make it like this :-
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
alignment: Alignment.center,
fit: StackFit.expand,
overflow: Overflow.visible,
children: <Widget>[
GradesAppBar(
title: "Grades",
gradientBegin: Colors.red[200],
gradientEnd: Colors.red,
),
Positioned(
top: -20,
left: MediaQuery.of(context).size.width / 2 - 150,
child: Container(
color: Colors.blue,
width: 300,
height: 60,
),
),
],
),
);
}
The most important thing; if your GradesAppBar extends PreferredSizeWidget I think you should replace it with Container and give it some cool decorations as you want :")

Related

How can I click on the stack item stuck in the bottom layer?

Below is a simple view of my code. It has two stack elements and both contain clickable content. the top element covers the bottom element, I can't click on the bottom element. what should I do?
`
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
///decoration
height: SizeConfig.screenHeight,
width: SizeConfig.screenWidth,
child: Stack(
children: [
Container(
width: SizeConfig.screenWidth,
height: SizeConfig.screenHeight! * 0.3,
///decoration
///child: content
///THIS IS FIXED CONTENT. LIKE AN 'HEADER'
///clickable contents here
),
SingleChildScrollView(
child: Container(
margin: EdgeInsets.only(top: SizeConfig.screenHeight! * 0.25),
constraints: BoxConstraints(
minHeight: SizeConfig.screenHeight! * 0.75,
maxHeight: double.infinity,
),
///decoration and child, content
///THIS IS CONTENT SIDE FOR PAGE.
///this is scrollable and when scrolling up it goes above the header, continues up
///looks like DraggableScrollableSheet
//////clickable contents here
),
)
],
),
),
),
);
}
`
IgnorePointer, AbsorbPointer etc. i tryed but i cant solve it.
thats my workaround below. its background for flexibleSpace of CustomScrollView Appbar.
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Container(
//color: HTKColors.the_green_color,
///decoration
height: SizeConfig.screenHeight,
width: SizeConfig.screenWidth,
child: Stack(
children: [
Container(
width: SizeConfig.screenWidth,
height: SizeConfig.screenHeight! * 0.3,
///decoration
),
CustomScrollView(
slivers: [
SliverAppBar(
expandedHeight: SizeConfig.screenHeight! * 0.25,
backgroundColor: Colors.transparent,
leading: const SizedBox(),
flexibleSpace: FlexibleSpaceBar(
collapseMode: CollapseMode.none,
background: SizedBox(
width: SizeConfig.screenWidth,
height: SizeConfig.screenHeight! * 0.25,
///my bottom element (header)
),
),
),
SliverList(
delegate: SliverChildListDelegate([
Container(
constraints: BoxConstraints(
minHeight: SizeConfig.screenHeight! * 0.75,
maxHeight: double.infinity,
),
///draggable top element
),
]),
),
],
),
],
),
),
),
);
}
This is exactly what I want:
The green area can reach infinite length and can be scrolled. when i scroll up should be able to go above the red area. and if I didn't scroll the green area and I can see the red area; I should be able to click on the elements in the red area.
sample code here:
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Stack(
children: [
Column(
children: [
Container(
width: SizeConfig.screenWidth,
height: SizeConfig.screenHeight! * 0.25,
color: Colors.red,
///clickable elements here
),
Container(
width: SizeConfig.screenWidth,
height: SizeConfig.screenHeight! * 0.75,
color: Colors.transparent
),
],
),
SingleChildScrollView(
child: Column(
children: [
Container(
width: SizeConfig.screenWidth,
height: SizeConfig.screenHeight! * 0.25,
color: Colors.transparent,
),
Container(
width: SizeConfig.screenWidth,
constraints: BoxConstraints(
minHeight: SizeConfig.screenHeight! * 0.75,
maxHeight: double.infinity,
),
///this elemend can be infinitely long by content
color: Colors.green
///clickable elements here
),
],
),
),
],
),
),
);
}
#eamirho3in

Stack Widget Not Scrolling in SCSV, Flutter

I'm using a Stack to Positioned one widget on top of an Image.asset widget, but the problem I have is that my whole Stack widget is not scrollable to see the whole content. I wrapped the Stack widget with a SingleChildScrollView but the problem still persists. If I wrap the Stack widget with a Containter and give the height: MediaQuery.of(context).size.height, it's scrollable but I can't still see the whole content of the page. Where is my mistake, that's what I'm wondering? With what widget should I wrap Stack or is there a better way for my problem? In short, I'm stacking a Column on top of an Image and I need the whole Stack widget to be scrollable so I can see the whole content of the Stack widget. Here is the code:
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey,
body: SafeArea(
child: SingleChildScrollView(
child: Stack(
overflow: Overflow.visible,
children: [
Image.asset(
'lib/modules/common/images/logo.png',
width: double.infinity,
height: 196.0,
),
Positioned(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
top: 136.0,
child: Column(
children: [
Container(), // some content inside the container
Container(), // // some content inside the container
],
),
),
],
),
),
),
);
}
Thanks in advance for the help!
if you mean to have a image on back and scrollable content at fron check this answer, if not let me know and share a prototype/image that you want.
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey,
body: SafeArea(
child: SingleChildScrollView(
child: SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 3,
child: Stack(
fit: StackFit.loose,
children: [
Align(
alignment: Alignment.topCenter,
child: Image.asset(
'assets/image.jpg',
width: double.infinity,
height: 196.0,
),
),
Positioned(
top: 136.0,
child: SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisSize: MainAxisSize.min,
children: List.generate(
2,
(index) => Container(
height: 100,
width: double.infinity,
color: index % 2 == 0
? Colors.amberAccent
: Colors.cyanAccent,
), // some content inside the container
// some content inside the container
),
),
),
),
],
),
),
),
),
);
}

How to set background image for scaffold?

I am trying to set a background Image for a screen which takes about 25% of the screen,positioned at the top.
I have tried,
#override
Widget build(BuildContext context) {
return Scaffold(
extendBodyBehindAppBar: true,
appBar: AppBar(
backgroundColor: Colors.transparent,
actions: [
IconButton(
icon: Icon(Icons.settings),
onPressed: () {
//Go to Settings Page
},
)
],
),
body: Container(
width: double.infinity,
alignment: Alignment.topCenter,
decoration: BoxDecoration(
image: DecorationImage(
fit: BoxFit.fitWidth,
image: AssetImage(
"assets/images/image1.png",
),
),
),
child: SingleChildScrollView(
child: Column(
children: [
Container(
height: 200,
width: 220,
color: Colors.purple,
),
Container(
height: 200,
width: 220,
color: Colors.pink,
),
It does not align itself to top.Is there any easier way?
I have tried using stack too.
This is what I am getting:
Expected.
Take container as the body of the Scaffold and then set your image as background image inside container decoration.
Don't forget to set the width and height for the container like this:
width : Mediaquery.of(context).size.width
height : Mediaquery.of(context).size.height

Swipe circle to open new Activity(page) in flutter

I want to open new page when I swipe the circle in the middle of the screen. that is when I swipe blue circle left a new page should open and when I swipe right another new page should open.
Similarly when I swipe pink circle bottom another new page should open
Here is my code:
import 'package:flutter/material.dart';
class FirstRoute extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
height: 300.0,
width: 150.0,
child: Stack(
children: <Widget>[
Positioned(
top: 25,
child: Container(
height: 150.0,
width: 150.0,
decoration: BoxDecoration(
shape:BoxShape.circle,
color:Colors.lightBlue,
),
),
),
Positioned(
bottom: 25,
child: Opacity(
opacity: 0.45,
child: Container(
height: 150.0,
width: 150.0,
decoration: BoxDecoration(
shape:BoxShape.circle,
color:Colors.pinkAccent,
),
),
),
),
],
),
),
),
);
}
}
wrap Positioned() with SwipeDetector() Widget
Have a look at this example
SwipeDetector(
onSwipeRight: () {
//push new page
Navigator.of(context).push(new MaterialPageRoute(builder: (BuildContext context) => new YourNewPage()));
},
child: //Your circle here
Positioned(
top: 25,
child: Container(
height: 150.0,
width: 150.0,
decoration: BoxDecoration(
shape:BoxShape.circle,
color:Colors.lightBlue,
),
),
),
)

Flutter - Overlay card widget on a container

In flutter, is it possible to place a part of a card on another container? In CSS, we would set margin-top to a negative value or use translate property. In flutter as we cannot set negative values to margin-top, is there an alternative to that?
Yes, you can acheive it with a Stack widget. You can stack a card over the background and provide a top or bottom padding.
A simple example would look like:
class StackDemo extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new Stack(
children: <Widget>[
// The containers in the background
new Column(
children: <Widget>[
new Container(
height: MediaQuery.of(context).size.height * .65,
color: Colors.blue,
),
new Container(
height: MediaQuery.of(context).size.height * .35,
color: Colors.white,
)
],
),
// The card widget with top padding,
// incase if you wanted bottom padding to work,
// set the `alignment` of container to Alignment.bottomCenter
new Container(
alignment: Alignment.topCenter,
padding: new EdgeInsets.only(
top: MediaQuery.of(context).size.height * .58,
right: 20.0,
left: 20.0),
child: new Container(
height: 200.0,
width: MediaQuery.of(context).size.width,
child: new Card(
color: Colors.white,
elevation: 4.0,
),
),
)
],
);
}
}
The output of the above code would look something like:
Hope this helps!
Screenshot:
Instead of hardcoding Positioned or Container, you should use Align.
Code:
#override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return Scaffold(
body: Stack(
children: [
Column(
children: [
Expanded(flex: 2, child: Container(color: Colors.indigo)),
Expanded(child: Container(color: Colors.white)),
],
),
Align(
alignment: Alignment(0, 0.5),
child: Container(
width: size.width * 0.9,
height: size.height * 0.4,
child: Card(
elevation: 12,
child: Center(child: Text('CARD', style: Theme.of(context).textTheme.headline2)),
),
),
),
],
),
);
}
Here is running example with overlay:
class _MyHomePageState extends State<MyHomePage> {
double _width = 0.0;
double _height = 0.0;
#override
Widget build(BuildContext context) {
_width = MediaQuery.of(context).size.width;
_height = MediaQuery.of(context).size.height;
return Scaffold(
backgroundColor: Colors.white,
body: Stack(
children: <Widget>[
// The containers in the background and scrollable
getScrollableBody(),
// This container will work as Overlay
getOverlayWidget()
],
),
);
}
Widget getOverlayWidget() {
return new Container(
alignment: Alignment.bottomCenter,
child: new Container(
height: 100.0,
width: _width,
color: Colors.cyan.withOpacity(0.4),
),
);
}
Widget getScrollableBody() {
return SingleChildScrollView(
child: new Column(
children: <Widget>[
new Container(
height: _height * .65,
color: Colors.yellow,
),
new Container(
height: _height * .65,
color: Colors.brown,
),
new Container(
margin: EdgeInsets.only(bottom: 100.0),
height: _height * .65,
color: Colors.orange,
),
],
),
);
}
}
Here is Result of code:
Scrollable Body under customised Bottom Bar