Reputation: 1503
I'm trying to make a specific view in which I have more than 1 "big" widget on screen. The idea is to show both a GridView (shrinkwrapped) with a maximum of 4 cards of close events, and a ListView (also shrinkwrapped) that can hold up to a couple dozens of music bands.
Both things could be on separated views, but it's a requirement to show these short grid + list in the home view. It also looks better, IMO. But Flutter is causing me problems with the scrolling.
Take a look at how it currently looks:
As for now, I'm capable of showing both the GridView and ListView, but the scroll works really, really bad. As for now, both widgets are wrapped inside a SingleChildScrollView, which I guess it's not a good solution since it doesn't have a single child. It is able to work if I hold the finger in a part of that parent widget (just like the title, or the black background), but not if I hold it on any of the widgets (gridview or scrollview).
My aim is to get the scroll functionality delegated to the parent widget, so wherever I put my finger, I can scroll the whole view and not only scroll a child view, as it currently happens.
This is my HomePage code:
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text(widget.title),
backgroundColor: Colors.indigo,
),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(padding: EdgeInsets.only(top: 30)),
Text(
'¡Bienvenido a Sonorio!',
style: TextStyle(fontSize: 24),
),
Padding(padding: EdgeInsets.only(top: 25)),
EventsList(key: new Key('test')),
ListView(
shrinkWrap: true,
padding: const EdgeInsets.all(8),
children: <Widget>[
Container(
height: 100,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 50,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
],
)
],
),
));
The EventsList widget is just a GridView that has shrinkWrap:
Widget build(BuildContext context) {
return FutureBuilder<List<Event>>(
future: new EventsService().getEventsForCoords(),
builder: (context, AsyncSnapshot<List<Event>> snapshot) {
if (snapshot.hasData) {
return Column(children: [
Text('Eventos musicales en tu zona: ',
style: TextStyle(
shadows: [
Shadow(
blurRadius: 2,
color: Colors.indigo[300],
offset: Offset.fromDirection(1, 1))
],
fontSize: 18,
fontFamily: "Roboto",
color: Colors.indigo[200],
fontWeight: FontWeight.bold)),
Padding(padding: EdgeInsets.only(bottom: 8)),
GridView.count(
crossAxisCount: 2,
shrinkWrap: true,
children: generateProximityEventCards(snapshot.data)),
]);
} else {
return CircularProgressIndicator();
}
});
}
How can I get this working, or at least, delegate child widgets scroll functionality, to the parent?
Thank you!
Upvotes: 0
Views: 3952
Reputation: 8978
According to the requirements I see that, you don't want child scroll, else you just want the scroll to happen on the layout, that is for ParentWidget
There are certain changes I would suggest to make that happen after looking at your code:
Column()
in place of ListView()
Widget
There are certain things, which I have changed in the code, so just look at the end result, and make the amendments.
GridView
uses my dummy Container()
Widget in place of your widget generateProximityEventCards(snapshot.data))
FutureBuilder
, cos, I am using the static data. So, just used Column()
part to show you the end resultLet us jump into the code directly
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(padding: EdgeInsets.only(top: 30)),
Text(
'¡Bienvenido a Sonorio!',
style: TextStyle(fontSize: 24),
),
Padding(padding: EdgeInsets.only(top: 25)),
EventsList(),
// Used column with padding for ListView
Padding(
padding: EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
Container(
height: 100,
color: Colors.amber[600],
child: const Center(child: Text('Entry A')),
),
Container(
height: 50,
color: Colors.amber[500],
child: const Center(child: Text('Entry B')),
),
Container(
height: 50,
color: Colors.amber[100],
child: const Center(child: Text('Entry C')),
),
],
)
)
]
)
)
);
}
}
// cusomt eventlist widget, you can make the changes eventually
class EventsList extends StatelessWidget{
Widget get myWidget => Container(
height: 50.0,
width: 50.0,
margin: EdgeInsets.only(right: 18.0, left: 18.0, bottom: 18.0),
decoration: BoxDecoration(
color: Colors.greenAccent,
borderRadius: BorderRadius.circular(12.0)
)
);
Widget build(BuildContext context) {
return Column(children: [
Text('Eventos musicales en tu zona: ',
style: TextStyle(
shadows: [
Shadow(
blurRadius: 2,
color: Colors.indigo[300],
offset: Offset.fromDirection(1, 1))
],
fontSize: 18,
fontFamily: "Roboto",
color: Colors.indigo[200],
fontWeight: FontWeight.bold)),
Padding(padding: EdgeInsets.only(bottom: 8)),
GridView.count(
crossAxisCount: 2,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(), //diables the scrolling
children: [
// my widget which I created
myWidget,
myWidget,
myWidget,
myWidget
]
),
]);
}
}
Result
Upvotes: 3