Zerok
Zerok

Reputation: 1503

Scrolling problem with various widgets in Flutter

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:

enter image description here

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

Answers (1)

Alok
Alok

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:

There are certain things, which I have changed in the code, so just look at the end result, and make the amendments.

  • Your GridView uses my dummy Container() Widget in place of your widget generateProximityEventCards(snapshot.data))
  • Did not use FutureBuilder, cos, I am using the static data. So, just used Column() part to show you the end result

Let 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

End Reuslt Gif

Upvotes: 3

Related Questions