简体   繁体   中英

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:

在此处输入图像描述

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!

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

结束结果 Gif

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM