Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pin Row to bottom of Scroll View on top of other UI widgets

I'm trying to pin a Row container that has a text field input and an adjacent icon button within a ScrollView. Unfortunately, the Row will stay at the bottom but not with the view of the screen so the user will have to scroll down to see the Row container. How can I pin the bottom bar to the screen so that it is always at the bottom within the view of the screen and over the top of the other objects in the ScrollView?

Bar UI:

class TextBarAtBottom extends StatelessWidget {
  TextEditingController commentController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Row(children: [
      // First child is TextInput
      Expanded(
          child: Container(
            child: TextFormField(
              autocorrect: false,
              decoration: new InputDecoration(
                labelText: "Some Text",
                labelStyle: TextStyle(fontSize: 16.0, color: Colors.black),
                fillColor: Colors.black,
                border: OutlineInputBorder(
                    borderSide: BorderSide(color: Colors.black)),
              ),
            ),
          )),
      // Second child is button
      IconButton(
        icon: Icon(Icons.send),
        iconSize: 16.0,
        onPressed: () {},
      )
    ]);
  }
}

Screen UI:

@override
Widget build(BuildContext context) {
  return MaterialApp(
        title: 'App',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: Scaffold(
            appBar: AppBar(
              title: Text('App'),
            ),
            body: SingleChildScrollView(
                child: Column(mainAxisSize: MainAxisSize.min, children: [
              Flexible(
                  fit: FlexFit.loose,
                  child: ExpandableTheme(
                      data: ExpandableThemeData(
                          iconColor: Colors.blue,
                          useInkWell: true,
                          animationDuration: const Duration(milliseconds: 500),
                          tapBodyToExpand: true,
                          tapHeaderToExpand: true,
                          tapBodyToCollapse: true,
                          hasIcon: true,
                          iconPlacement: ExpandablePanelIconPlacement.right),
                      child: ExpandablePanel(
                          header: Text(widget.postData.title,
                              style: TextStyle(fontSize: 24)),
                          collapsed: Text(widget.postData.text,
                              style: TextStyle(fontSize: 16),
                              softWrap: true,
                              maxLines: 10,
                              overflow: TextOverflow.ellipsis),
                          expanded: Text(widget.postData.text,
                              style: TextStyle(fontSize: 16),
                              softWrap: true)))),
              // Second child is spacing
              SizedBox(height: 16),
              // Third child is list view of Cards that are populated from the request post
              Flexible(
                  fit: FlexFit.loose,
                  child: Container(
                    child: FutureBuilder<Map<String, String>>(
                      future: post,
                      builder: (context, snapshot) {
                        if (snapshot.hasData) {
                          return ListView.builder(
                              shrinkWrap: true,
                              itemCount: snapshot.data.length,
                              itemExtent: 128.0,
                              itemBuilder: (BuildContext context, int index) {
                                return Card(Text('$index'));
                              });
                        } else if (snapshot.hasError) {
                          return Flex(direction: Axis.horizontal, children: [
                            Expanded(
                              child: new Container(),
                            )
                          ]);
                        }
                        return CircularProgressIndicator();
                      },
                    ),
                  )),
              // Fourth child is text bar and send button
              Flexible(fit: FlexFit.loose, child: TextBarAtBottom())
            ]))));
  }

Screenshot

like image 843
Black Avatar asked Oct 20 '25 20:10

Black


1 Answers

OutPut Screenshot

Check my code, it's having textfield at the bottom, and scrollview in the center.

Problem with your code is you are adding Textfield inside scrollview so always at the end of SingleChildScrollview.

Solution: Add your SingleChildScrollView inside column view with Expanded widget. and add your Textfield as the second child to Column widget. Now TextField will be at the bottom and the rest of the space will be taken by SingleChildScrollView.

import 'package:flutter/material.dart';

    class Design extends StatefulWidget {
     @override
     _DesignState createState() => _DesignState();
    }

    class _DesignState extends State<Design> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
          title: Text('TextField at Bottom'),
        ),
          body: Column(
            children: <Widget>[
              Expanded(
                child: SingleChildScrollView(
                   child: Column(
                      children: <Widget>[
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                    Text('Flutter'),
                ],
              ),
            ),
          ),
          Row(children: [
            // First child is TextInput
            Expanded(
                child: Container(
              child: TextFormField(
                autocorrect: false,
                decoration: new InputDecoration(
                  labelText: "Some Text",
                  labelStyle: TextStyle(fontSize: 16.0, color: Colors.black),
                  fillColor: Colors.black,
                  border: OutlineInputBorder(
                      borderSide: BorderSide(color: Colors.black)),
                ),
              ),
            )),
            // Second child is button
            IconButton(
              icon: Icon(Icons.send),
              iconSize: 16.0,
              onPressed: () {},
            )
          ])
        ],
      ),
    );
    }
   }
like image 74
MSARKrish Avatar answered Oct 22 '25 19:10

MSARKrish



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!