Flutter: ListView not scrollable, not bouncing

前端 未结 6 2161
醉梦人生
醉梦人生 2021-02-12 21:49

I have the following example (tested on an iPhone X, iOS 11):

import \'package:flutter/material.dart\';

void main() => runApp(new MyApp());

class MyApp exte         


        
相关标签:
6条回答
  • 2021-02-12 21:58

    **

    Use container height for scrolling and also use physics: AlwaysScrollableScrollPhysics(), controller: controller,

    **

    Container(
        width: 400,
        child: Drawer(
          child: Stack(children: [
            Container(
              height: MediaQuery.of(context).size.height-80,
              child: ListView(
                controller: controller,
                padding: EdgeInsets.zero,
                
                physics: AlwaysScrollableScrollPhysics(),
                children: [
                  Container(
                    height: 300,
                    padding: EdgeInsets.symmetric(vertical: 20, horizontal: 10),
                    child: DrawerHeader(
                      child:Stack(children: [
                        Center(
                          child: Column(
                            children: [
                              nullCatcher(image) == "" ? Image.asset("assets/images/doctor.png",height: 90,width: 90,) : Image.network(
                                "$image",
                                height: 90,
                                width: 90,
                              ),
                              SizedBox(width: 30,),
                              Text("$name",style: TextStyle(color: Colors.grey[700],fontWeight: FontWeight.bold,fontSize: 25),),
                              Text("$specialty",style: TextStyle(color: Colors.grey[600]),),
                            ],
                          ),
                        ),
                        Positioned(
                            right: 0,bottom: 10,
                            child: Text("Version: 1.0.0",style: TextStyle(color: Colors.orange),))
                      ],),
    
                    ),
                  ),
                  ListTile(
                    contentPadding: EdgeInsets.zero,
                    title: Container(
                        height: 70,
                        padding: EdgeInsets.symmetric(horizontal: 30),
                        decoration: drawerListDecoration,
                        child: Row(
                          children: [
                            Container(
                                height: 35,width: 35,
                                decoration: BoxDecoration(
                                    color: Theme.of(context).accentColor,
                                    borderRadius: BorderRadius.circular(100)
                                ),
                                child: Icon(Icons.attach_file,color: Colors.white,size: 20,)),
                            SizedBox(width: 20,),
                            Text('Create Appointment'),
                          ],
                        )),
                    onTap: () {
                      Navigator.pushReplacement(context, MaterialPageRoute(builder: (__)=>CreateAppointment()));
                      // Update the state of the app.
                      // ...
                    },
                  ),
                  ListTile(
                    contentPadding: EdgeInsets.zero,
                    title: Container(
                        height: 70,
                        padding: EdgeInsets.symmetric(horizontal: 30),
                        decoration: drawerListDecoration,
                        child: Row(
                          children: [
                            Container(
                                height: 35,width: 35,
                                decoration: BoxDecoration(
                                    color: Theme.of(context).accentColor,
                                    borderRadius: BorderRadius.circular(100)
                                ),
                                child: Icon(Icons.attach_file,color: Colors.white,size: 20,)),
                            SizedBox(width: 20,),
                            Text('Appointment / Prescription List'),
                          ],
                        )),
                    onTap: () {
                      Navigator.pushReplacement(context, MaterialPageRoute(builder: (__)=>AppointmentList()));
                      // Navigator.pop(context);
                    },
                  ),
                  Container(
                    height: 70,
                    padding: EdgeInsets.symmetric(horizontal: 30 ),
                    color: Colors.grey[200],
                    child: Row(
                      children: [
                        Container(
                            height: 35,width: 35,
                            decoration: BoxDecoration(
                                color: Theme.of(context).accentColor,
                                borderRadius: BorderRadius.circular(100)
                            ),
                            child: Icon(Icons.attach_file,color: Colors.white,size: 20,)),
                        SizedBox(width: 20,),
                        Text("Clinical Options:",style: TextStyle(fontWeight: FontWeight.bold,color: Colors.grey[600]),),
                      ],
                    ),
                  ),
                  ListTile(
                    contentPadding: EdgeInsets.zero,
                    title: Container(
                        height: childHeight,
                        padding: EdgeInsets.only(left: childPaddeing),
                        // decoration: drawerListDecoration,
                        child: Row(
                          children: [
                            lineDesign(),
                            SizedBox(width: 20,),
                            Text('Chief Complain'),
                          ],
                        )),
                    onTap: () {
                      Navigator.pushReplacement(context, MaterialPageRoute(builder: (__)=>AppointmentList()));
                      // Navigator.pop(context);
                    },
                  ),
                  ListTile(
                    contentPadding: EdgeInsets.zero,
                    title: Container(
                        height: 50,
                        padding: EdgeInsets.symmetric(horizontal: 45),
                        decoration: drawerListDecoration,
                        child: Row(
                          children: [
                            lineDesign(),
                            SizedBox(width: 20,),
                            Text('On Examination'),
                          ],
                        )),
                    onTap: () {
                      Navigator.pushReplacement(context, MaterialPageRoute(builder: (__)=>AppointmentList()));
                      // Navigator.pop(context);
                    },
                  ),
                  ListTile(
                    contentPadding: EdgeInsets.zero,
                    title: Container(
                        height: 70,
                        padding: EdgeInsets.symmetric(horizontal: 30),
                        decoration: drawerListDecoration,
                        child: Row(
                          children: [
                            Container(
                                height: 35,width: 35,
                                decoration: BoxDecoration(
                                    color: Theme.of(context).accentColor,
                                    borderRadius: BorderRadius.circular(100)
                                ),
                                child: Icon(Icons.attach_file,color: Colors.white,size: 20,)),
                            SizedBox(width: 20,),
                            Text('Examination Category'),
                          ],
                        )),
                    onTap: () {
                      Navigator.pushReplacement(context, MaterialPageRoute(builder: (__)=>AppointmentList()));
                      // Navigator.pop(context);
                    },
                  ),
                  ListTile(
                    contentPadding: EdgeInsets.zero,
                    title: Container(
                        height: 70,
                        padding: EdgeInsets.symmetric(horizontal: 30),
                        decoration: drawerListDecoration,
                        child: Row(
                          children: [
                            Container(
                                height: 35,width: 35,
                                decoration: BoxDecoration(
                                    color: Theme.of(context).accentColor,
                                    borderRadius: BorderRadius.circular(100)
                                ),
                                child: Icon(Icons.attach_file,color: Colors.white,size: 20,)),
                            SizedBox(width: 20,),
                            Text('Diagnosis'),
                          ],
                        )),
                    onTap: () {
                      Navigator.pushReplacement(context, MaterialPageRoute(builder: (__)=>AppointmentList()));
                      // Navigator.pop(context);
                    },
                  ),
                  ListTile(
                    contentPadding: EdgeInsets.zero,
                    title: Container(
                        height: 70,
                        padding: EdgeInsets.symmetric(horizontal: 30),
                        decoration: drawerListDecoration,
                        child: Row(
                          children: [
                            Container(
                                height: 35,width: 35,
                                decoration: BoxDecoration(
                                    color: Theme.of(context).accentColor,
                                    borderRadius: BorderRadius.circular(100)
                                ),
                                child: Icon(Icons.attach_file,color: Colors.white,size: 20,)),
                            SizedBox(width: 20,),
                            Text('Investigations'),
                          ],
                        )),
                    onTap: () {
                      Navigator.pushReplacement(context, MaterialPageRoute(builder: (__)=>AppointmentList()));
                      // Navigator.pop(context);
                    },
                  ),
    
                ],
              ),
            ),
            Positioned(
                bottom: 0,
                left: 0,
                right: 0,
                child: ButtonTheme(
                  child: RaisedButton(
                    color: Colors.red[900],
                    onPressed: (){
                      if(blocState is LogoutInLoading){}else logoutAlert(blocContext);
                    },
                    child: Container(
                      height: 70,
                      child:blocState is LogoutInLoading ? Container( height: 20,width: 20,margin: EdgeInsets.symmetric(vertical: 25), child: CircularProgressIndicator(valueColor: AlwaysStoppedAnimation(Colors.white),),) : Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Text("Sign Out",style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold,fontSize: 25),),
                          SizedBox(width: 20,),
                          Icon(Icons.logout,color: Colors.white,)
                        ],
                      ),
                    ),
                  ),
                )
            )
          ],),
        ),
      );
    
    0 讨论(0)
  • 2021-02-12 21:59

    I found a solution how to track the offset with lists that have a smaller content height than the viewport. Use a NotificationListener together with a CustomScrollView in the build() method like this:

    import 'package:flutter/material.dart';
    
    void main() => runApp(new MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          theme: new ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: new MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => new _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      ScrollController _controller = new ScrollController();
    
      @override
      Widget build(BuildContext context) {
        return new NotificationListener(
          onNotification: _handleScrollPosition,
            child: new CustomScrollView(
                slivers: [
                  new SliverList(
                      delegate: new SliverChildListDelegate([
                        new Container(
                          height: 40.0,
                          color: Colors.blue,
                        ),
                        new Container(
                          height: 40.0,
                          color: Colors.red,
                        ),
                        new Container(
                          height: 40.0,
                          color: Colors.green,
                        ),
                      ])
                  )
                ]
            )
        );
      }
    
      bool _handleScrollPosition(ScrollNotification notification) {
        print(notification.metrics.pixels);
        return true;
      }
    }
    

    As long as there is no solution with a ScrollController only (or a "better" (more elegant)) solution, I will accept this as the answer.

    0 讨论(0)
  • 2021-02-12 22:00

    Creates scroll physics using AlwaysScrollableScrollPhysics that always lets the user scroll.

    For scroll with bouncing effect Just supply physics: BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics) to your scroller. That will make it always scrollable, even when there isn't content that overflows

    const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics())
    

    Here is full example

    ListView(
      padding: EdgeInsets.all(8.0),
      physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
      children: _listData.map((i) {
        return ListTile(
          title: Text("Item $i"),
        );
      }).toList(),
    );
    

    0 讨论(0)
  • 2021-02-12 22:03

    Just add AlwaysScrollableScrollPhysics

    ListView(
            physics: const AlwaysScrollableScrollPhysics(),
            children :  [...]
    }
    
    0 讨论(0)
  • 2021-02-12 22:09

    I think this solution is better without CustomScrollView. Just use NotificationListener to wrap the ListView.

      Widget noti = new NotificationListener(
        child:listView,
        onNotification: (ScrollNotification note){
          print(note.metrics.pixels.toInt());
        },
      );
    

    I have test it , Bounce is effective

    0 讨论(0)
  • 2021-02-12 22:21

    To always have the scroll enabled on a ListView you can wrap the original scroll phisics you want with the AlwaysScrollableScrollPhysics class. More details here. If you want you can specify a parent or rely on the default.

    Here is your example with the option added:

    import 'package:flutter/material.dart';
    
    void main() => runApp(new MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          theme: new ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: new MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      MyHomePage({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _MyHomePageState createState() => new _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      ScrollController _controller = new ScrollController();
    
      @override
      Widget build(BuildContext context) {
        return new ListView(
            physics: const AlwaysScrollableScrollPhysics(), // new
            controller: _controller,
            children: <Widget>[
              new Container(
                height: 40.0,
                color: Colors.blue,
              ),
              new Container(
                height: 40.0,
                color: Colors.red,
              ),
              new Container(
                height: 40.0,
                color: Colors.green,
              ),
            ]
        );
      }
    }
    
    0 讨论(0)
提交回复
热议问题