Search code examples
flutterbuttondrawertableofcontents

is it possible to create a table of contents button in Flutter?


I create a listTile in enDrawer. What I want is, For example, if I press the Headline Two button, the page will scroll automatically to Headline Two. Plz help me Masters ..

this is my ListTile screenshot: https://drive.google.com/file/d/1oni6jsQtSgzYMhclHm6QwdozSKtPPglE/view?usp=sharing

this is my Page screenshot: https://drive.google.com/file/d/10x--L3NZh5LGGfw-VbpZCWrfNcENR2Kq/view?usp=sharing

I want when I pressed Headline Two in Drawer, the page automatic scrolling to Headline Two like in this screenshot: https://drive.google.com/file/d/1GZlJnWuFmYK9cYxuTlOroiZBTw9oVvMU/view?usp=sharing

this is my full code :

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

class MyStotry extends StatefulWidget {
  @override
  _MyStotryState createState() => _MyStotryState();
}

class _MyStotryState extends State<MyStotry> {
  @override
  Widget build(BuildContext context) {
    SystemChrome.setEnabledSystemUIOverlays([]);
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Color(0xFF41407C),
        title: Text('The Story of ANU'),
      ),
      endDrawer: Drawer(
        child: Container(
          child: ListView(
            children: <Widget>[
              Container(
                height: 250,
                child: DrawerHeader(
                  decoration: BoxDecoration(color: Color(0xFF41407C)),
                  child: Stack(
                    children: <Widget>[
                      Center(
                        child: Text(
                          'Table of Content',
                          style: TextStyle(
                              color: Color(0xFFF8F8F8), fontSize: 20.0),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
              ListTile(onTap: () {}, title: Text('Headline One')),
              ListTile(onTap: () {}, title: Text('Headline Two')),
              ListTile(onTap: () {}, title: Text('Headline Three')),
              ListTile(onTap: () {}, title: Text('Headline Four')),
              ListTile(onTap: () {}, title: Text('Headline Five')),
              ListTile(onTap: () {}, title: Text('Headline Six')),
              ListTile(onTap: () {}, title: Text('Headline Seven')),
              ListTile(onTap: () {}, title: Text('Headline Eight')),
              ListTile(onTap: () {}, title: Text('Headline Nine')),
              ListTile(onTap: () {}, title: Text('Headline Ten')),
              ListTile(onTap: () {}, title: Text('Headline Eleven')),
            ],
          ),
        ),
      ),
      body: SingleChildScrollView(
        child: Padding(
          padding: EdgeInsets.all(20),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Headline1(headline1: 'Headline One'),
              Content(
                  content:
                      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'),
              Content(
                  content:
                      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. '),
              Headline2(headline2: 'Headline Two'),
              Content(
                  content:
                      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'),
              Headline2(headline2: 'Headline Three'),
              Content(
                  content:
                      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'),
              Content(
                  content:
                      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. '),
              Headline2(headline2: 'Headline Four'),
              Content(
                  content:
                      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'),
              Content(
                  content:
                      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. '),
              Headline2(headline2: 'Headline Five'),
              Content(
                  content:
                      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'),
              Content(
                  content:
                      'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. '),
            ],
          ),
        ),
      ),
    );
  }
}

class Headline1 extends StatelessWidget {
  Headline1({this.headline1});
  final String headline1;
  @override
  Widget build(BuildContext context) {
    return Text(
      headline1,
      style: TextStyle(
        fontWeight: FontWeight.w800,
        fontSize: 22,
        fontFamily: 'Georgia',
        color: Color(0xFF010101),
      ),
      textAlign: TextAlign.center,
    );
  }
}

class Headline2 extends StatelessWidget {
  Headline2({this.headline2});
  final String headline2;
  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.only(top: 10, bottom: 10),
      child: Text(
        headline2,
        style: TextStyle(
          fontFamily: 'Georgia',
          fontWeight: FontWeight.w800,
          fontSize: 18,
          color: Color(0xFF010101),
        ),
        textAlign: TextAlign.center,
      ),
    );
  }
}

class Content extends StatelessWidget {
  Content({this.content});
  final String content;
  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.only(bottom: 10),
      child: Text(
        content,
        style: TextStyle(
          height: 1.5,
          fontFamily: "Georgia",
          fontSize: 15.0,
          color: Color(0xFF010101),
        ),
        textAlign: TextAlign.justify,
      ),
    );
  }
}

Solution

  • You can copy paste run full code below
    Step 1: Modify class Headline2 and add Key

     class Headline2 extends StatelessWidget {
      Headline2({Key key, this.headline2}) : super(key: key);
    

    Step 2: Use List<GlobalKey> and ScrollController

     List<GlobalKey> headLineKeyList = [
        GlobalKey(),
        GlobalKey(),
        GlobalKey(),
        GlobalKey(),
        GlobalKey()
      ];
      ScrollController _scrollController = ScrollController();
    

    Step 3: Put ScrollController to SingleChildScrollView

    SingleChildScrollView(
            controller: _scrollController,
    

    Step 4: Headline pass key: headLineKeyList[0]

     Headline1(key: headLineKeyList[0], headline1: 'Headline One'),
    

    Step 5: ListTile's onTap call Scrollable.ensureVisible(headLineKeyList[0].currentContext

     ListTile(
          onTap: () {
            Scrollable.ensureVisible(headLineKeyList[0].currentContext,
                duration: const Duration(milliseconds: 500));
          },
     
    

    working demo

    enter image description here

    full code

    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home: MyStotry(),
        );
      }
    }
    
    class MyStotry extends StatefulWidget {
      @override
      _MyStotryState createState() => _MyStotryState();
    }
    
    class _MyStotryState extends State<MyStotry> {
      List<GlobalKey> headLineKeyList = [
        GlobalKey(),
        GlobalKey(),
        GlobalKey(),
        GlobalKey(),
        GlobalKey()
      ];
      ScrollController _scrollController = ScrollController();
    
      @override
      Widget build(BuildContext context) {
        SystemChrome.setEnabledSystemUIOverlays([]);
        return Scaffold(
          appBar: AppBar(
            backgroundColor: Color(0xFF41407C),
            title: Text('The Story of ANU'),
          ),
          endDrawer: Drawer(
            child: Container(
              child: ListView(
                children: <Widget>[
                  Container(
                    height: 250,
                    child: DrawerHeader(
                      decoration: BoxDecoration(color: Color(0xFF41407C)),
                      child: Stack(
                        children: <Widget>[
                          Center(
                            child: Text(
                              'Table of Content',
                              style: TextStyle(
                                  color: Color(0xFFF8F8F8), fontSize: 20.0),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ),
                  ListTile(
                      onTap: () {
                        Scrollable.ensureVisible(headLineKeyList[0].currentContext,
                            duration: const Duration(milliseconds: 500));
                      },
                      title: Text('Headline One')),
                  ListTile(
                      onTap: () {
                        Scrollable.ensureVisible(headLineKeyList[1].currentContext,
                            duration: const Duration(milliseconds: 500));
                      },
                      title: Text('Headline Two')),
                  ListTile(
                      onTap: () {
                        Scrollable.ensureVisible(headLineKeyList[2].currentContext,
                            duration: const Duration(milliseconds: 500));
                      },
                      title: Text('Headline Three')),
                  ListTile(
                      onTap: () {
                        Scrollable.ensureVisible(headLineKeyList[3].currentContext,
                            duration: const Duration(milliseconds: 500));
                      },
                      title: Text('Headline Four')),
                  ListTile(
                      onTap: () {
                        Scrollable.ensureVisible(headLineKeyList[4].currentContext,
                            duration: const Duration(milliseconds: 500));
                      },
                      title: Text('Headline Five')),
                  ListTile(onTap: () {}, title: Text('Headline Six')),
                  ListTile(onTap: () {}, title: Text('Headline Seven')),
                  ListTile(onTap: () {}, title: Text('Headline Eight')),
                  ListTile(onTap: () {}, title: Text('Headline Nine')),
                  ListTile(onTap: () {}, title: Text('Headline Ten')),
                  ListTile(onTap: () {}, title: Text('Headline Eleven')),
                ],
              ),
            ),
          ),
          body: SingleChildScrollView(
            controller: _scrollController,
            child: Padding(
              padding: EdgeInsets.all(20),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  Headline1(key: headLineKeyList[0], headline1: 'Headline One'),
                  Content(
                      content:
                          'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'),
                  Content(
                      content:
                          'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. '),
                  Headline2(key: headLineKeyList[1], headline2: 'Headline Two'),
                  Content(
                      content:
                          'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'),
                  Headline2(key: headLineKeyList[2], headline2: 'Headline Three'),
                  Content(
                      content:
                          'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'),
                  Content(
                      content:
                          'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. '),
                  Headline2(key: headLineKeyList[3], headline2: 'Headline Four'),
                  Content(
                      content:
                          'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'),
                  Content(
                      content:
                          'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. '),
                  Headline2(key: headLineKeyList[4], headline2: 'Headline Five'),
                  Content(
                      content:
                          'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'),
                  Content(
                      content:
                          'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. '),
                ],
              ),
            ),
          ),
        );
      }
    }
    
    class Headline1 extends StatelessWidget {
      Headline1({Key key, this.headline1}) : super(key: key);
      final String headline1;
      @override
      Widget build(BuildContext context) {
        return Text(
          headline1,
          style: TextStyle(
            fontWeight: FontWeight.w800,
            fontSize: 22,
            fontFamily: 'Georgia',
            color: Color(0xFF010101),
          ),
          textAlign: TextAlign.center,
        );
      }
    }
    
    class Headline2 extends StatelessWidget {
      Headline2({Key key, this.headline2}) : super(key: key);
      final String headline2;
      @override
      Widget build(BuildContext context) {
        return Container(
          padding: EdgeInsets.only(top: 10, bottom: 10),
          child: Text(
            headline2,
            style: TextStyle(
              fontFamily: 'Georgia',
              fontWeight: FontWeight.w800,
              fontSize: 18,
              color: Color(0xFF010101),
            ),
            textAlign: TextAlign.center,
          ),
        );
      }
    }
    
    class Content extends StatelessWidget {
      Content({this.content});
      final String content;
      @override
      Widget build(BuildContext context) {
        return Container(
          padding: EdgeInsets.only(bottom: 10),
          child: Text(
            content,
            style: TextStyle(
              height: 1.5,
              fontFamily: "Georgia",
              fontSize: 15.0,
              color: Color(0xFF010101),
            ),
            textAlign: TextAlign.justify,
          ),
        );
      }
    }