How do they work? : The Stack Widget and The Position Widget - flutter

Please, would you look at the attached screenshot and tell me where that band of off-white is coming from?? (red arrow.)
I want the rounded container to display text right down to the bottom of the screen--any text-overflow will simply be scrolled by the SingleChildScrollView widget, but the container just gets thinner and thinner while that block of grey just stays there??
Been working in Flutter since March of 2018, and Flutter's layout widgets are still a mystery!
Here is the code:
#override
Widget build(BuildContext context) {
return Scaffold(
// primary: false,
appBar: AppBar(
title: I10n.t('Playhouse'),
centerTitle: true,
automaticallyImplyLeading: false,
elevation: 0,
excludeHeaderSemantics: true,
),
endDrawer: const ScrapBookDrawer(),
body: SafeArea(
child: Column(
children: [
/// Submodule Name | Short Description
Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.only(left: 10, top: 4),
child: Text(
'${widget.subTask['subName']} |',
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
),
const Expanded(
child: Padding(
padding: EdgeInsets.only(top: 4),
child: Text(
'Submodule description',
),
),
),
],
),
Stack(
alignment: AlignmentDirectional.topCenter,
children: <Widget>[
/// Large Picture
Container(
height: 500, // double.infinity,
child: Crop(
interactive: false,
backgroundColor: Colors.white,
dimColor: Colors.white,
controller: CropController(),
child: Image.memory(
base64.decode(
con.submodule['image'],
),
),
),
),
Positioned(
left: 0,
right: 0,
top: 300,
/// Rounded Container
child: Container(
height: 500,
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(60),
topRight: Radius.circular(60),
),
color: Colors.white,
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
/// Task Name and Number
Padding(
padding: const EdgeInsets.only(top: 30, bottom: 20),
child: Text(
widget.subTask['name'],
style: const TextStyle(
fontWeight: FontWeight.bold,
),
),
),
/// Short Description or Title
Padding(
padding: const EdgeInsets.only(bottom: 20),
child: Text(widget.subTask['short_description']),
),
/// Long Description
Flexible(
flex: 300,
child: SingleChildScrollView(
child: Text(widget.subTask['long_description']),
),
),
],
),
),
)
],
),
],
),
),
);
}

I got rid of the white area by increasing height of the first Container in the Stack. Seems like it is just a default background that's not covered with anything.

Related

Changing the design of a widget after scrolling in sliver app bar

I want to design this ui bellow in flutter the problem is the categories list as you can see it changes on scroll the items design change from vertical to horizontal, here my code down bellow, I m wondering how can I do that on flutter
Click here to see the design I m talking about, you can notice that under the search bar the list design changes, I want to do that
class FavouritesScreen extends StatelessWidget {
const FavouritesScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: CustomScrollView(
physics: BouncingScrollPhysics(),
slivers: [
SliverAppBar(
expandedHeight: 104,
floating: true,
pinned: true,
snap: false,
titleSpacing: 0,
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
title: Padding(
padding: const EdgeInsets.only(left: 16.0, right: 16.0, top: 4),
child: Text(
"My List",
style: TextStyle(color: Gray500, fontSize: 26),
),
),
bottom: AppBar(
elevation: 0,
titleSpacing: 0,
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
title: Padding(
padding:
const EdgeInsets.only(left: 16.0, right: 16.0, top: 4),
child: Container(
height: 48,
child: Row(
children: [
Expanded(
child: Container(
height: 48,
width: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Gray100,
),
child: Row(
children: [
SizedBox(
width: 10,
),
Icon(
Icons.search,
color: Gray300,
),
SizedBox(
width: 10,
),
Text(
"Search",
style: TextStyle(
color: Gray300,
),
),
],
),
),
),
SizedBox(
width: 16,
),
Container(
height: 48,
width: 48,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Colors.black),
child: Icon(Icons.date_range),
)
],
),
),
),
),
),
SliverToBoxAdapter(
child: Column(
children: [
//the list of the menu
],
),
)
],
),
),
);
}
}

Strange Top Padding on my second AppBar Flutter

Screen of the strange top padding of my app
I have made two classes : the first has a first AppBar and calls the second one that has also a sticky AppBar and display a list of scrollable Items. However, I have a strange top padding in the second AppBar. I have tried a lot of stuff but nothing seems to work.
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
extendBodyBehindAppBar: true,
bottomNavigationBar: BottomNavBar(0, _currentAccount),
appBar: PreferredSize(
preferredSize:
Size.fromHeight(MediaQuery.of(context).size.height / 7),
child: Column(
children: [
Container(
width: MediaQuery.of(context).size.width,
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: <Color>[
Color(0xFF894c56),
Color(0xFFa80d0d)
])),
child: Padding(
padding: const EdgeInsets.only(bottom: 30),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.only(top: 50, left: 5),
child: Text(
'Votre évenement ',
style: TextStyle(
fontSize: 15, color: Colors.grey),
)),
Padding(
padding: const EdgeInsets.only(top: 5, left: 5),
child: Text(
event,
style: const TextStyle(
color: Colors.white, fontSize: 17),
),
)
])),
)
],
),
),
body: ListPrestat('Traiteur', _currentAccount)
// ListPrestat('Traiteur', _currentAccount)
));
}
This is the code of my first class that calls the ListPrestat class here under :
#override
Widget build(BuildContext context) {
return SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height ,
// -(MediaQuery.of(context).size.height / 6 + 56),
child: CustomScrollView(
slivers: [
SliverAppBar(
toolbarHeight: 50,
expandedHeight: 0,
backgroundColor: const Color(0xFFDCDCDC),
pinned: true,
leading: IconButton(
icon: const Icon(
Icons.arrow_back,
color: Color(0xFFDC3535),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => MainScreen(_currentAccount)),
);
},
),
centerTitle: true,
shadowColor: Colors.black,
elevation: 10,
bottom: const PreferredSize(
preferredSize: Size.fromHeight(0),
child: TagList(ListCat: 'brouette')),
title: Container(
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.all(MediaQuery.of(context).size.width / 4),
child: Text(
_currentCat,
style: const TextStyle(
color: Colors.black,
fontSize: 16.0,
fontWeight: FontWeight.w700,
),
)),
),
SliverFixedExtentList(
itemExtent: 110.0,
delegate: SliverChildListDelegate(
[
for (int index = 0; index < 5; index++)
CustomListItem2(
thumbnail: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child: AspectRatio(
child: Image.network(
growableList[index],
width: 100.0,
height: 100.0,
fit: BoxFit.fill,
),
aspectRatio: 1 / 1,
)),
title: 'Chez Luigi',
subtitle: 'Les meilleurs pizza hors d\'italie.',
ListCat: 'Food Truck',
),
],
),
)
],
),
);
}
Do you have any idea what can have caused this padding and how to resolve this problem ?
wrap your secound class with scaffold
Scaffold(
body: SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height ,),
...................
)

Flutter CustomScrollView „stick“ card on top

I want to create a list in Flutter with a small preview of the content before the user sees all information on a new screen.
Therefor I build a simple list with Sliver-Cards:
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Cards'),
backgroundColor: Colors.blue,
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 5),
child: CustomScrollView(
shrinkWrap: false,
slivers: <Widget>[
_buildHeader(),
_buildCard('1', Colors.white, Colors.red, Colors.transparent),
_buildCard('2', Colors.white, Colors.blue, Colors.red),
_buildCard('3', Colors.white, Colors.green, Colors.blue),
…
],
),
),
);
}
Widget _buildHeader() => SliverStickyHeader(
header: Container(
height: 50,
color: Colors.white,
padding: const EdgeInsets.symmetric(horizontal: 16),
alignment: Alignment.topLeft,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Center(
child: Text(
"Card-Header",
style: TextStyle(
fontWeight: FontWeight.bold, color: Colors.black),
),
),
],
),
),
sliver: SliverToBoxAdapter(
child: Container(
height: 20,
),
),
);
Widget _buildCard(
String logo, Color logoColor, Color cardColor, Color prevColor) =>
SliverStickyHeader(
header: GestureDetector(
child: Stack(
children: <Widget>[
Container(
height: 16,
color: prevColor,
),
Container(
height: 60,
decoration: BoxDecoration(
color: cardColor,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16))),
padding: const EdgeInsets.symmetric(horizontal: 16),
alignment: Alignment.bottomLeft,
child: Text(
logo,
style:
TextStyle(color: logoColor, fontWeight: FontWeight.bold),
),
),
],
),
),
sliver: SliverToBoxAdapter(
child: Container(
height: 20,
color: cardColor,
),
),
);
Here’s a Screenshot:
The only thing missing is the method to show a small preview of the content, which I want to stick to the top of the list. For example, anything like in this GitHub post: https://github.com/loopeer/CardStackView/blob/master/screenshot/screenshot1.gif
Is it possible to create a method like this in flutter?

Flutter Stack Widget has Whitespace for some unknown reason

I'm still having trouble with Flutter's approach to laying out widgets.
There's this 'whitespace' that I would remove or cover (see red arrows).
How would I extend the 'image' up to the menu bar?
As you can see in the code below, I'm using a Stack widget.
I don't know what is making the 'whitespace' between the Stack widget and the appbar?? Possibly, it's due to the Crop widget (a third-party package). I'll look into that now, but decided to post this question anyway.
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: I10n.t('Playhouse'),
centerTitle: true,
automaticallyImplyLeading: false,
elevation: 0,
excludeHeaderSemantics: true,
),
endDrawer: const ScrapBookDrawer(),
body: Stack(
children: <Widget>[
Crop(
interactive: false,
backgroundColor: Colors.white,
dimColor: Colors.white,
controller: CropController(),
child: Image.memory(
base64.decode(
con.submodule['image'],
),
),
),
SafeArea(
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Flexible(
child: Text(
widget.subTask['subName'],
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
const Flexible(
child: Text(
'Submodule description',
),
),
]),
const Spacer(),
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Colors.white),
child: Column(
children: <Widget>[
/// Task Name and Number
Padding(
padding: const EdgeInsets.only(
top: 30,
bottom: 20,
),
child: Text(
widget.subTask['name'],
style: const TextStyle(
fontSize: 26,
fontWeight: FontWeight.bold,
),
),
),
/// Short Description or Title
Padding(
padding: const EdgeInsets.only(
top: 10,
),
child: Text(widget.subTask['short_description']),
),
const SizedBox(height: 30),
Flexible(
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Text(widget.subTask['long_description']),
),
),
],
),
),
)
],
),
)
],
),
);
}
It seems it is actually due to Crop widget. It automatically determines the aspect ratio of your picture. You should manually set your aspect ratio by adding the aspectRatio parameter to your CropController, something like this:
Crop(
interactive: false,
backgroundColor: Colors.white,
dimColor: Colors.white,
controller: CropController(aspectRatio: 0.75),
child: Image.memory(
base64.decode(
con.submodule['image'],
),
),
)
In your case it seems that aspect ratio of ~0.75 works the best, play around with this to find your best value.

SingleChildScrollView in Column Widget

The SingleChildScrollView is surrounded by the Flexible widget
because there's an overflow error. However, placing the Flexible
then makes the text too small!?
Please, how can I do this in a better way?
#override
Widget build(BuildContext context) {
return Scaffold(
// primary: false,
appBar: AppBar(
title: I10n.t('Playhouse'),
centerTitle: true,
automaticallyImplyLeading: false,
elevation: 0,
excludeHeaderSemantics: true,
),
endDrawer: const ScrapBookDrawer(),
body: SafeArea(
child: Column(
children: [
/// Submodule Name | Short Description
Flexible(
flex: 3,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Padding(
padding: const EdgeInsets.only(top: 4),
child: Text(
widget.subTask['subName'],
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
const Flexible(
child: Padding(
padding: EdgeInsets.only(top: 4),
child: Text(
'Submodule description',
),
),
),
],
),
),
Flexible(
flex: 5,
fit: FlexFit.tight,
child: Stack(
alignment: AlignmentDirectional.topCenter,
children: <Widget>[
/// Large Picture
Crop(
interactive: false,
backgroundColor: Colors.white,
dimColor: Colors.white,
controller: CropController(),
child: Image.memory(
base64.decode(
con.submodule['image'],
),
),
),
Positioned(
left: 0,
right: 0,
top: 200,
/// Rounded Container
child: Material(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(60),
topRight: Radius.circular(60),
),
child: Column(
children: <Widget>[
Container(
height: 225,
child: Column(
children: <Widget>[
/// Task Name and Number
Padding(
padding: const EdgeInsets.only(
top: 30, bottom: 20,),
child: Text(
widget.subTask['name'],
style: const TextStyle(
fontSize: 26,
fontWeight: FontWeight.bold,
),
),
),
/// Short Description or Title
Padding(
padding: const EdgeInsets.only(
top: 10, bottom: 30,),
child:
Text(widget.subTask['short_description']),
),
/// Long Description
Flexible(
child: SingleChildScrollView(
child:
Text(widget.subTask['long_description']),
),
),
],
),
),
],
),
),
),
],
),
),
],
),
),
);
}
In the next version below, I've gotten rid of the Positioned widget, but now (marked with red arrows) I don't see how to get rid of the whitespace?
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: I10n.t('Playhouse'),
centerTitle: true,
automaticallyImplyLeading: false,
elevation: 0,
excludeHeaderSemantics: true,
),
endDrawer: const ScrapBookDrawer(),
body: Stack(
children: <Widget>[
Crop(
interactive: false,
backgroundColor: Colors.white,
dimColor: Colors.white,
controller: CropController(),
child: Image.memory(
base64.decode(
con.submodule['image'],
),
),
),
SafeArea(
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Flexible(
child: Text(
widget.subTask['subName'],
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
const Flexible(
child: Text(
'Submodule description',
),
),
]),
const Spacer(),
Expanded(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Colors.white),
child: Column(
children: <Widget>[
/// Task Name and Number
Padding(
padding: const EdgeInsets.only(
top: 30,
bottom: 20,
),
child: Text(
widget.subTask['name'],
style: const TextStyle(
fontSize: 26,
fontWeight: FontWeight.bold,
),
),
),
/// Short Description or Title
Padding(
padding: const EdgeInsets.only(
top: 10,
bottom: 30,
),
child: Text(widget.subTask['short_description']),
),
const SizedBox(height: 30),
Flexible(
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Text(widget.subTask['long_description']),
),
),
],
),
),
)
],
),
)
],
),
);
}
Knowing that the second one is the closest to what you need, to remove the whitespace you only need to remove the bottom paddings and the sizedBox, because you are the one controlling the whitespaces with those widgets and set a width size to your container with long and short description, like this:
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: I10n.t('Playhouse'),
centerTitle: true,
automaticallyImplyLeading: false,
elevation: 0,
excludeHeaderSemantics: true,
),
endDrawer: const ScrapBookDrawer(),
body: Stack(
children: <Widget>[
Crop(
interactive: false,
backgroundColor: Colors.white,
dimColor: Colors.white,
controller: CropController(),
child: Image.memory(
base64.decode(
con.submodule['image'],
),
),
),
SafeArea(
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Flexible(
child: Text(
widget.subTask['subName'],
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
),
const Flexible(
child: Text(
'Submodule description',
),
),
]),
const Spacer(),
Expanded(
child: Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30),
color: Colors.white),
child: Column(
children: <Widget>[
/// Task Name and Number
Padding(
padding: const EdgeInsets.only(
top: 30,
bottom: 20,
),
child: Text(
widget.subTask['name'],
style: const TextStyle(
fontSize: 26,
fontWeight: FontWeight.bold,
),
),
),
/// Short Description or Title
Padding(
padding: const EdgeInsets.only(
top: 10,
),
child: Text(widget.subTask['short_description']),
),
Flexible(
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Text(widget.subTask['long_description']),
),
),
],
),
),
)
],
),
)
],
),
);
}