I am trying to achieve scroll in Flutter Web where I have few containers which are stacked and I use SingleChildScrollView to scroll the widget. However, when I scroll the first container everything working fine but the second one which is a child of the second container responds to the scroll without completing the initial one. And also is there a way to make a sticky header for the second container. How can I make the 3rd container(orange) to scroll after the 2nd(blue) one is finished scrolling? Here is what I am trying to achieve:
https://yobithemes.com/demo/html/freda/dark-video-index.html
And here what I got so far:
class MainScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
IntroScreen(),
SingleChildScrollView(
child: Container(
child: Column(
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).size.height - 100,
),
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
color: Colors.blue,
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(
height: MediaQuery.of(context).size.height,
),
Container(
padding: EdgeInsets.only(top: 100),
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
color: Colors.orange,
),
],
),
),
),
],
),
),
),
],
),
);
}
}
You can achieve it by using sliver.
SliverToBoxAdapter fill the transparent area with screen height - app bar height.
SliverAppBar: make it sticky by setting floating and pin to true
class MainScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
IntroScreen(),
CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: Container(
height: MediaQuery.of(context).size.height - 50,
),
),
SliverAppBar(
// toolbarHeight: 50,
floating: true,
pinned: true,
title: Container(
child: Center(child: Text('Header')),
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => Container(
height: MediaQuery.of(context).size.height-50,
color: Colors.primaries[index % Colors.primaries.length],
),
),
),
],
),
],
),
);
}
}
Related
In the picture below, I tried using the SizedBox Widget and I set the height:
SizedBox(
height: MediaQuery.of(context).size.height / 5.9,
),
The second solution is I try to use LayoutBuilder widget and builder and I specify the height: constraints.maxHeight * 0.4 but I'm getting the same result.
Here's the code:
body: SingleChildScrollView(
child: Column(
children: [
Stack(
children: <Widget>[
_buildCoverImage(screenSize),
SafeArea(
child: SingleChildScrollView(
child: Column(
children: <Widget>[
SizedBox(height:MediaQuery.of(context).size.height / 5.9),
_buildProfileImage(),
_buildFullName(context),
_buildStatContainer(context),
]
),
),
),
],
),
],
),
),
);
output
Hope you want something like this, while using LayoutBuilder use it at top level of widget tree.
example code
import 'package:flutter/material.dart';
class BackSide extends StatelessWidget {
const BackSide({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: LayoutBuilder(
builder: (context, constraints) => SizedBox(
height: constraints.maxHeight,
width: constraints.maxWidth,
child: Stack(
fit: StackFit.expand,
alignment: Alignment.topCenter,
children: <Widget>[
// _buildCoverImage(screenSize),
Container(
height: constraints.maxHeight,
width: constraints.maxWidth,
color: Colors.amberAccent,
child: Text("Background"),
),
SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SizedBox(
height: constraints.maxHeight * .4,
),
...List.generate(
15,
(index) => Container(
height: 100,
width: double.infinity,
color: index % 2 == 0
? Colors.pinkAccent
: Colors.cyanAccent,
child: Text("item $index"),
)).toList(),
// _buildProfileImage(),
// _buildFullName(context),
// _buildStatContainer(context),
],
),
)
],
),
),
),
);
}
}
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
),
),
),
),
],
),
),
),
),
);
}
Here is my code
child: Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(),
drawer: MyDrawer(),
body: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
// direction: Axis.vertical,
children: [
Container(
height: 400,
child: Text('PageOne'),
),
IntrinsicHeight(
child: Expanded(
child: Container(
width: double.infinity,
color: Colors.grey,
child: Text(
'Hi',
textAlign: TextAlign.center,
),
),
),
),
],
),
),
),
I want this grey container in the screenshot fill the height as min height, I need it responsively with rotate the screen phone and for all phone screen size, it's only takes static height size when use SingleChildScrollView because unlimited height is available, i try to find way to make him take the remaining height of the screen as min height of container.
any ideas?
If you do know the height of the top part, you could use a mix of LayoutBuilder and ConstrainedBox like so:
import 'dart:math';
import 'package:flutter/material.dart';
main() {
runApp(MaterialApp(home: MyApp()));
}
class MyApp extends StatelessWidget {
final double headerHeight = 400;
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(),
body: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
// direction: Axis.vertical,
children: [
Container(
color: Colors.red,
height: headerHeight,
child: Text('PageOne'),
),
ConstrainedBox(
constraints: new BoxConstraints(
minHeight: max(0, constraints.maxHeight - headerHeight),
),
child: Container(
width: double.infinity,
color: Colors.grey,
child: Text(
'Hi',
textAlign: TextAlign.center,
),
),
),
],
),
);
}
),
);
}
}
If you don't know the height of the top part, I would use key (or keys) to get their size and use the same widget tree as above.
I am trying to leave a container fixed and the other part of the screen that can do some scrolling is there a possibility to replicate not the screen, only these two events?
return SingleChildScrollView(
physics: NeverScrollableScrollPhysics(),
child: Container(
child: Column(
children: <Widget>[
Container(
height: 200,
width: double.infinity,
color: Colors.red,
),
SingleChildScrollView(
child: Container(color: Colors.blue,height: 1000,width: double.infinity,))
/* body(context, screenWidth, screenHeight),
bottmtop(context), */
],
),
),
);
You can use this exmaple as it.
If You want to user list than use SliverList in place of SliverFillRemaining;
class HeadState extends State<Head> {
#override
Widget build(BuildContext context) {
var screenHeight = MediaQuery.of(context).size.height;
var screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
bottomNavigationBar: BottomNavigationBar(items: []),
body: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
expandedHeight: screenHeight / 4,
flexibleSpace: Container(
color: Colors.red,
),
),
SliverFillRemaining(
child: Container(
height: screenHeight - screenHeight / 4,
color: Colors.blue,
),
)
],
),
);
}
}
I have a code that contains a column, and in the column there are 3 widgets, a widget container that has a height of 200 and a width of 200 in red, and the second widget contains a container with a child a transform scale that contains an image that I want to scale, and widget 3 contains the same as the first widget, every time I scale the image, what happens to the second container is always past the first container but does not occur with continaer to 3, if in css I will definitely use zindex, is there some kind of flutter zindex
this is the code
SingleChildScrollView(
physics: AlwaysScrollableScrollPhysics(),
child: Column(
children: <Widget>[
Container(
height: 300,
color: Colors.red,
),
Container(
// height: 397,
child: Transform.scale(
scale: 2.0,
child: Container(
width: MediaQuery.of(context).size.width,
child: Image(
image: NetworkImage(
"https://s3-ap-southeast-1.amazonaws.com//kriyapeople/8fa208d6-1486-4028-bd23-243581b4d3a7"),
fit: BoxFit.fitWidth,
),
),
),
),
Container(
height: 300,
color: Colors.red,
),
],
)));
and the result of that code
Use Stack widget,
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
children: <Widget>[
_buildHeader(),
for (final i in List.generate(20, (i) => i))
ListTile(title: Text("Tile $i")),
],
),
);
}
_buildHeader() {
double height = 250;
return SizedBox(
height: height,
child: Stack(
children: <Widget>[
Column(
children: <Widget>[
Container(
color: Colors.red,
height: height * 2 / 3,
),
Container(
color: Colors.grey[200],
height: height / 3,
),
],
),
Align(
alignment: Alignment.bottomCenter,
child: Image(
image: NetworkImage(
"https://s3-ap-southeast-1.amazonaws.com//kriyapeople/8fa208d6-1486-4028-bd23-243581b4d3a7"),
height: height * 2/3,
width: height * 2/3,
fit: BoxFit.cover,
),
),
],
),
);
}
}