This is my simple code:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: MyMobileBody(),
);
}
}
class MyMobileBody extends StatelessWidget {
const MyMobileBody({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) => Scaffold(
backgroundColor: Colors.deepPurple[200],
appBar: AppBar(
title: Text('M O B I L E'),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
// video section
Padding(
padding: const EdgeInsets.all(8.0),
child: AspectRatio(
aspectRatio: 16 / 9,
child: Container(
color: Colors.deepPurple[400],
),
),
),
// comment section & recommended videos
Expanded(
child: ListView.builder(
itemCount: 8,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
color: Colors.deepPurple[300],
height: 120,
),
);
},
),
)
],
),
),
),
);
}
}
It gets the bottom overflow yellow/black error. I want to make the AspectRatio widget scrollable but using SingleChildScrollView didn't work. I also tried ConstrainedBox like below but it didn't work too:
// comment section & recommended videos
ConstrainedBox(
constraints: BoxConstraints(maxHeight: constraints.maxHeight),
child: Expanded(
child: ListView.builder(
itemCount: 8,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
color: Colors.deepPurple[300],
height: 120,
),
);
},
),
),
)
Add shrinkWrap : true to the ListView, then remove the Expanded widget that's wrapping the list view. Also add mainAxisSize : MainAxisSize.min. Then add SingleChildScrollView to the body of scaffold and the column inside it.
class MyMobileBody extends StatelessWidget {
const MyMobileBody({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) => Scaffold(
backgroundColor: Colors.deepPurple[200],
appBar: AppBar(
title: Text('M O B I L E'),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize : MainAxisSize.min,//<--here
children: [
// video section
Padding(
padding: const EdgeInsets.all(8.0),
child: AspectRatio(
aspectRatio: 16 / 9,
child: Container(
color: Colors.deepPurple[400],
),
),
),
// comment section & recommended videos
//<--here removed expanded
ListView.builder(
shrinkWrap:true,//<--here
itemCount: 8,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
color: Colors.deepPurple[300],
height: 120,
),
);
},
)
],
),
),
),
),
);
}
}
Related
I have a CustomScrollView widget and inside of it there is a Column which contains a nested SliverList instead of ListView.builder because of some performance issues, and the problem is I cannot use SliverList inside the Column.
Below is the full code just copy paste it and run it on you emulator to understand more about the problem.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return const Scaffold(
body: CustomScrollView(
slivers: [
SliverToBoxAdapter(child: WidgetTest()),
],
),
);
}
}
class WidgetTest extends StatefulWidget {
const WidgetTest({Key? key}) : super(key: key);
#override
State<WidgetTest> createState() => _WidgetTestState();
}
class _WidgetTestState extends State<WidgetTest> {
#override
Widget build(BuildContext context) {
return Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 22),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Title",
style: Theme.of(context).textTheme.headline1,
),
],
),
),
SizedBox(
height: 260,
child: SliverList(
delegate: SliverChildBuilderDelegate(
childCount: 5,
(context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 80,
width: 220,
color: Colors.red,
),
);
},
),
),
),
],
);
}
}
The issue using Sliver List inside SizedBox.
SizedBox(
height: 260,
child: SliverList(
delegate: SliverChildBuilderDelegate(
You can Use ListView.builder( here,
SizedBox(
height: 260,
child: ListView.builder(
itemCount: 5,
itemBuilder: (context, index) => Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 80,
width: 220,
color: Colors.red,
),
)),
),
else, you need to wrap with CustomScrollView to use SliverList
SizedBox(
height: 260,
child: CustomScrollView(
slivers: [
SliverList(
delegate: SliverChildBuilderDelegate(
childCount: 5,
(context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
height: 80,
width: 220,
color: Colors.red,
),
);
},
),
)
],
)),
Inside sliver put sliver widget, and other section use normal widget. Also, ListView use sliver inside it.
CustomScrollView requires you to input a list of slivers, not simple widgets. Try wrapping your ’TestWidget’ in a SliverToBoxAdapter instead :)
5. I am having an issue with scrolling. The outer container ListView
is scrolling fine, but when I grab the gridView elements the scroll effect doesn't work. What is it that I am missing here? (GIF below)
HomeScreen() has HomeBody() widget; HomeBody() has ListView, whose children are BuildSectionContainers() which have a services widgets as child.
class HomeScreem extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Stethoscope',
style: TextStyle(
color: Theme.of(context).accentColor,
fontSize: 24,
fontFamily: GoogleFonts.pacifico().fontFamily,
letterSpacing: 1.5),
),
centerTitle: true,
),
// APP BODY
body: HomeBody(),
);
}
}
class HomeBody extends StatelessWidget {
#override
Widget build(BuildContext context) {
final healthService = Provider.of<HealthServices>(context);
final service = healthService.services;
return ListView(
children: [
//
BuildSectionContainer(
healthService: healthService,
service: service,
sectionTitle: 'SERVICES',
child: Container(
height: 245,
child: BuildGeneralServicesGrid(
healthService: healthService,
service: service,
),
),
),
//
BuildSectionContainer(
healthService: healthService,
service: service,
sectionTitle: 'EMERGENCY SERVICES',
child: Container(
height: 245,
child: BuildEmergencyServicesGrid(
healthService: healthService,
service: service,
),
),
),
],
);
}
}
class BuildEmergencyServicesGrid extends StatelessWidget {
const BuildEmergencyServicesGrid({
Key? key,
required this.healthService,
required this.service,
}) : super(key: key);
final HealthServices healthService;
final List<HealthService> service;
#override
Widget build(BuildContext context) {
return GridView.builder(
itemCount: healthService.services.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 1,
mainAxisSpacing: 1,
mainAxisExtent: 120,
),
itemBuilder: (context, index) => GestureDetector(
child: Card(
color: Theme.of(context).primaryColor.withOpacity(0.1),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
padding: const EdgeInsets.all(8.0),
child: service[index].icon,
),
Container(
padding: const EdgeInsets.symmetric(horizontal: 8.0),
child: Text(
service[index].serviceName,
style: Theme.of(context).textTheme.bodyText2,
textAlign: TextAlign.center,
),
),
],
),
),
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => AudioConsultation(),
));
},
),
);
}
}
The issue happens because, the gridview interferes with the listview scrolling. You can set the physics property of your Gridview to NeverScrollableScrollPhysics to fix the issue.
GridView.builder(
// Disable scrolling for grid
physics: NeverScrollableScrollPhysics(),
// Your remaining code
),
does anyone know why my draggable scrollable sheet doesn't work or why I can't see it?
I tried it in another way it worked, but I didn't use the SafeArea-Widget,
import 'package:flutter/material.dart';
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(100.0),
child: AppBar(
//AppBar
),
body: SafeArea(
child: ListView(
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 20),
child: Text(
dateday,
style: TextStyle(
color: Color(0xff2C8E5D),
fontSize: 150,
),
),
),
SizedBox.expand(
child: DraggableScrollableSheet(builder:
(BuildContext context, ScrollController scrollController) {
return Container(
color: Colors.red,
child: ListView.builder(
controller: scrollController,
itemCount: 25,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text("Item $index"));
}),
);
}),
),
],
),
),
);
}
}
Thanks for your help!
Replace the ListView with a Stack:
body: SafeArea(
child: Stack(
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 20),
child: Text(
dateday,
style: TextStyle(
color: Color(0xff2C8E5D),
fontSize: 150,
),
),
),
SizedBox.expand(
child: DraggableScrollableSheet(
builder:
(BuildContext context, ScrollController scrollController) {
return Container(
color: Colors.red,
child: ListView.builder(
controller: scrollController,
itemCount: 25,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text("Item $index"));
}),
);
}),
),
],
),
),
You can use LayoutBuilder and BoxConstraints to provide height and use Expanded flex to control DraggableScrollableSheet's scroll area
code snippet
SafeArea(
child: LayoutBuilder(builder: (context, constraints) {
return ConstrainedBox(
constraints: BoxConstraints(maxWidth: constraints.maxWidth),
child: Column(
children: <Widget>[
Expanded(
flex: 1,
child: Padding(
padding: EdgeInsets.only(left: 20),
child: Text(
"dateday",
...
Expanded(
flex: 3,
child: SizedBox.expand(
working demo
full code
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('DraggableScrollableSheet'),
),
body: SafeArea(
child: LayoutBuilder(builder: (context, constraints) {
print(constraints.maxWidth);
print(constraints.minWidth);
return ConstrainedBox(
constraints: BoxConstraints(maxWidth: constraints.maxWidth),
child: Column(
children: <Widget>[
Expanded(
flex: 1,
child: Padding(
padding: EdgeInsets.only(left: 20),
child: Text(
"dateday",
style: TextStyle(
color: Color(0xff2C8E5D),
fontSize: 150,
),
),
),
),
Expanded(
flex: 3,
child: SizedBox.expand(
child: DraggableScrollableSheet(builder:
(BuildContext context,
ScrollController scrollController) {
return Container(
color: Colors.red,
child: ListView.builder(
controller: scrollController,
itemCount: 25,
itemBuilder: (BuildContext context, int index) {
return ListTile(title: Text("Item $index"));
}),
);
}),
),
),
],
),
);
}),
));
}
}
I am getting an error when I wrap my container in the column widget. I need 2 containers in a column but when I wrap it in column widget it's showing this error
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1694 pos 12: 'hasSize'
Showing this in Column line error
Here is my code
class _PlaceListState extends State<PlaceList> {
final List _places = [
{'name': 'Hunza', 'where': 'Gilgit Baltistan'},
{'name': 'Skardu' ,'where': 'Gilgit Baltistan'},
{'name': 'Murree', 'where': 'Gilgit Baltistan'},
];
#override
Widget build(BuildContext context) {
return Column(children: <Widget>[
Container(
margin: EdgeInsets.only(left: 40),
width: MediaQuery.of(context).size.width * 0.5,
child: ListView.builder(
itemCount: _places.length,
itemBuilder: (ctx, int index) {
return Container(
padding: EdgeInsets.only(top: 50),
child: Column(
children: <Widget>[
Text(_places[index]['name'], style: TextStyle(fontSize: 20),),
Container(
padding: EdgeInsets.only(top: 20),
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: Card(
elevation: 40.0,
child: Container(
width: 200,
child: Image(image: AssetImage('assets/images/500place.jpg')),
),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 7),
child: Row(
children: <Widget>[
Icon(Icons.favorite_border, size: 20),
Spacer(),
Text(
_places[index]['where'],
),
],
)
),
],
),
);
}),
)
],);
}
}
The screen output i use Navigation rale so that's why I set the width and its working fine without Column widget
You can copy paste run full code below
Step 1: Provide height when use PlaceList() , you can use Expanded(child: PlaceList())
Step 2: add shrinkWrap: true for ListView
Step 3: Use Expaneded flex to provide height for Container() 1 and 2
Column(
children: <Widget>[
Expanded(
flex: 3,
...
Expanded(
flex: 1,
child: Center(child: Container(child: Text("Second Container"))))
working demo
full code
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(child: PlaceList()),
],
),
),
);
}
}
class PlaceList extends StatefulWidget {
#override
_PlaceListState createState() => _PlaceListState();
}
class _PlaceListState extends State<PlaceList> {
final List _places = [
{'name': 'Hunza', 'where': 'Gilgit Baltistan'},
{'name': 'Skardu', 'where': 'Gilgit Baltistan'},
{'name': 'Murree', 'where': 'Gilgit Baltistan'},
{'name': 'abc', 'where': 'def'},
];
#override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Expanded(
flex: 3,
child: Container(
margin: EdgeInsets.only(left: 40),
width: MediaQuery.of(context).size.width * 0.5,
child: ListView.builder(
shrinkWrap: true,
itemCount: _places.length,
itemBuilder: (ctx, int index) {
return Container(
padding: EdgeInsets.only(top: 50),
child: Column(
children: <Widget>[
Text(
_places[index]['name'],
style: TextStyle(fontSize: 20),
),
Container(
padding: EdgeInsets.only(top: 20),
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: Card(
elevation: 40.0,
child: Container(
width: 200,
child: Image(
image: AssetImage(
'assets/images/500place.jpg')),
),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 7),
child: Row(
children: <Widget>[
Icon(Icons.favorite_border, size: 20),
Spacer(),
Text(
_places[index]['where'],
),
],
)),
],
),
);
}),
),
),
Expanded(
flex: 1,
child: Center(child: Container(child: Text("Second Container"))))
],
);
}
}
try adding height: // define height in double to your container
Add the shrinkWrap property to your ListView as seen below:
child: ListView.builder(
itemCount: _places.length,
shrinkWrap: true,
itemBuilder: (ctx, int index) {
return Container(...
Setting the shrinkWrap to true would result in the list wrapping its content and be as big as its children permits
You could also add a height to your Container
return Container(
height: 90,
...
)
I have a chat widget that I've been having trouble with given the unique header. Finally figured out how to position the TextComposer at the base of the app and all looks great, however the ListView where the chat's occur overlaps the header after a certain number of text entries. I've been trying to figure out how to position the ListView.builder so that it stays below the header (_buildImage and _buildTopHeader) and doesn't overlap such as in the image below. Unfortunately I haven't been having any luck. Any suggestions would be greatly appreciated!
Thanks!
Header Overlap
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: <Widget>[
Expanded(
child: Stack(children: <Widget>[
_buildIamge(),
_buildTopHeader(),
Container(
alignment: Alignment.center,
child: new ListView.builder(
padding: new EdgeInsets.all(8.0),
reverse: true,
itemBuilder: (_, int index) => _messages[index],
itemCount: _messages.length,
)),
]),
),
Container(
decoration:
new BoxDecoration(color: Theme.of(context).cardColor),
height: 50.0,
child: _buildTextComposer(),
alignment: Alignment.bottomCenter,
),
],
),
),
resizeToAvoidBottomPadding:false,
);
}
Stack renders its children list in order from top to bottom, with stuff on the bottom rendered over things at the top (it makes sense, I promise). So if you want the ListView to be rendered at the bottom of everything else, put it at the top of the children list:
Stack(
children: <Widget>[
Container(
alignment: Alignment.center,
child: new ListView.builder(
padding: new EdgeInsets.all(8.0),
reverse: true,
itemBuilder: (_, int index) => _messages[index],
itemCount: _messages.length,
),
),
_buildIamge(),
_buildTopHeader(),
],
),
Take a try with Positioned
Demo:
import 'package:flutter/material.dart';
class StackPositionPage extends StatefulWidget {
StackPositionPage({Key key, this.title}) : super(key: key);
final String title;
#override
_StackPositionPageState createState() => _StackPositionPageState();
}
class _StackPositionPageState extends State<StackPositionPage> {
var _headerHeight = 100.0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: buildBody(context),
);
}
Widget buildBody(BuildContext context) {
return SafeArea(
child: Column(
children: <Widget>[
Expanded(
child: Stack(children: <Widget>[
_buildIamge(),
_buildTopHeader(),
Positioned(
top: _headerHeight,
left: 0,
right: 0,
bottom: 0,
child: ListView.builder(
padding: new EdgeInsets.all(8.0),
itemBuilder: (_, int index) => Padding(
padding: const EdgeInsets.all(16.0),
child: _buildMessage(index),
),
),
),
]),
),
Container(
color: Colors.blue,
height: 50.0,
alignment: Alignment.bottomCenter,
child: Center(
child: Text("Composer"),
),
),
],
),
);
}
Text _buildMessage(int index) => Text("Message " + (index + 1).toString());
Container _buildTopHeader() {
return Container(
height: _headerHeight,
color: Colors.pink,
child: Center(
child: Text("Header"),
),
);
}
Container _buildIamge() {
return Container(
color: Colors.grey,
);
}
}