flutterscrollablepageviews

Combine SingleChildScrollView and PageView in Flutter


I created two forms, and added them to a PageView. Each form has 6 TextFormField. When I tap on the last 2 TextFormField, the keyboard shows up over these fields and hides them. What I need is to scroll up the form to show these fields when I tap each one and the keyboard is visible. For this approach I tried using a SingleChildScrollView under PageView like in the example, but it doesn't do what I need. How can I fix this?

Widget build(BuildContext context) {
    return Scaffold(
        resizeToAvoidBottomPadding: false,
        body: PageView(
            children: <Widget>[
            _sampleForm(),
            _sampleForm(),  
            ],
        ),
    )
}

_sampleForm(){
    return Container(
        margin: const EdgeInsets.fromLTRB(0, 0, 0, 10),
        width: MediaQuery.of(context).size.width,
        child: SingleChildScrollView(
            child: Column(
                children: <Widget>[
                    Form(
                        child: Column(
                            children: <Widget>[
                                TextFormField(...),
                                TextFormField(...),
                                TextFormField(...),
                                TextFormField(...),
                                TextFormField(...),
                                TextFormField(...),
                            ],
                        ),
                    ),
                ],
            ),  
        ),
    );
}

Solution

  • I have tested this to work.

    class SO extends StatefulWidget {
      @override
      _SOState createState() => _SOState();
    }
    
    class _SOState extends State<SO> {
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(""),
          ),
          body: PageView(
            children: <Widget>[
              _sampleForm("Page 1"),
              _sampleForm("Page 2"),
            ],
          ),
        );
      }
    
      _sampleForm(String title) {
        return SingleChildScrollView(
          child: Padding(
            padding: const EdgeInsets.all(32.0),
            child: Column(
              children: <Widget>[
                Form(
                  child: Column(
                    children: <Widget>[
                      ListTile(title: Text(title, textAlign: TextAlign.center)),
                      for (int i = 0; i < 10; i++) TextFormField(decoration: InputDecoration(hintText: "field ${i+1}"),),
                    ],
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }
    

    Just some extra padding to show the content is what you need.