Home > Mobile >  How can I add a programmatic scroll down to a list view builder which is inside a Modal Bottom Sheet
How can I add a programmatic scroll down to a list view builder which is inside a Modal Bottom Sheet

Time:03-05

I am using a modal bottom sheet to display a list of challenges the user has faced. When the user clicks on an icon : the bottom sheet comes up and the list builds. All this is fine.

I am using a scrollController on the main screen for another list. When the user adds an item, I call _scrollDown(), a method I created to get an automatic scroll down (on the main screen) and this works fine. I would like the same behavior in the bottom sheet. The problem is that I don't know where I can call my _scrollDown() method. The user clicks on "My Challenges", then the bottom sheet comes up and the list builds.... then it should scroll down... but I don't see where in the code I can add the method...

Here is the modal sheet code : (the gesture detector is on the icon used to get the list of challenges)

 GestureDetector(
                  onTap: () {
                    showModalBottomSheet<void>(
                      isScrollControlled: true,
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.only(
                          topLeft: Radius.circular(20.0),
                          topRight: Radius.circular(20.0),
                        ),
                      ),
                      context: context,
                      builder: (BuildContext context) {
                        return Container(
                          height: MediaQuery.of(context).size.height - 80,
                          child: SingleChildScrollView(
                            padding: EdgeInsets.only(
                                bottom:
                                    MediaQuery.of(context).viewInsets.bottom),
                            child: Column(
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: <Widget>[
                                Container(
                                  alignment: Alignment.topRight,
                                  child: IconButton(
                                      icon: Icon(
                                        Icons.cancel,
                                        color: Colors.red[900],
                                        size: uD.largeFont3,
                                      ),
                                      onPressed: () {
                                        Navigator.pop(context);
                                      }),
                                ),
                                Container(
                                  alignment: Alignment.topCenter,
                                  margin: const EdgeInsets.only(bottom: 20),
                                  child: Text(
                                    uD.selectedIoLanguage == Language.french
                                        ? 'Mes défis'.toUpperCase()
                                        : 'My Challenges'.toUpperCase(),
                                    textAlign: TextAlign.center,
                                    style: TextStyle(
                                      color: Colors.indigo[900],
                                      fontSize: uD.largeFont3,
                                    ),
                                  ),
                                ),
                                Container(
                                  decoration: BoxDecoration(
                                      border: Border(
                                          top: BorderSide(
                                        color: Colors.orange[200]!,
                                        width: 3,
                                      )),
                                      gradient: LinearGradient(
                                          colors: [
                                            Colors.orange[200]!,
                                            Colors.orange[50]!,
                                            Colors.orange[100]!,
                                            Colors.orange[200]!
                                          ],
                                          begin: Alignment.topLeft,
                                          end: Alignment.bottomLeft,
                                          stops: [0, 0.2, 0.5, 0.8])),
                                  height:
                                      MediaQuery.of(context).size.height - 163,
                                  child: uD.defis.length > 0
                                      ? ListView.builder(
                                          controller: _scrollController,
                                          cacheExtent: 2000,
                                          padding: const EdgeInsets.all(20),
                                          itemCount: uD.defis.length,
                                          itemBuilder: (context, index) {
                                            return MyDefisCard(
                                              index: index,
                                              score: uD.defis[index].score,
                                              date: uD.defis[index].date,
                                              time: uD.defis[index].time,

CodePudding user response:

Move your bottom sheet builder result into a StatefulWidget, let's say it's called BottomSheetContent

showModalBottomSheet<void>(
  isScrollControlled: true,
  shape: const RoundedRectangleBorder(
    borderRadius: BorderRadius.only(
      topLeft: Radius.circular(20.0),
      topRight: Radius.circular(20.0),
    ),
  ),
  context: context,
  builder: (BuildContext context) => BottomSheetContent(),
);

Inside the new widget, create a new ScrollController (note that in your code you are using the same ScrollController from the list in the previous route)

class _BottomSheetContentState extends State<BottomSheetContent> {
  ScrollController _scrollController = ScrollController();
  @override
  void initState() {
    super.initState();

    WidgetsBinding.instance!.addPostFrameCallback((_) {
      // _scrollController.animateTo()
      // same logic as in _scrollDown
    });
  }

  @override
  Widget build(BuildContext context) {
    // return bottom sheet content 
  }
} 
  • Related