首页 > 解决方案 > 将 Row 固定到其他 UI 小部件顶部的 Scroll View 底部

问题描述

我正在尝试将Row具有文本字段输入和相邻图标按钮的容器固定在ScrollView. 不幸的是,Row它将停留在底部,但不会出现在屏幕视图中,因此用户必须向下滚动才能看到Row容器。如何将底部栏固定到屏幕上,使其始终位于屏幕视图中的底部,并位于屏幕中其他对象的顶部ScrollView

酒吧界面:

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: () {},
      )
    ]);
  }
}

屏幕界面:

@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())
            ]))));
  }

截屏

标签: flutterflutter-layout

解决方案


输出截图

检查我的代码,它的底部有文本字段,中间有滚动视图。

您的代码的问题是您在滚动视图中添加文本字段,因此始终位于 SingleChildScrollview 的末尾。

解决方案: 使用 Expanded 小部件在列视图中添加 SingleChildScrollView。并将您的 Textfield 作为第二个子项添加到 Column 小部件。现在 TextField 将位于底部,其余空间将由 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: () {},
            )
          ])
        ],
      ),
    );
    }
   }

推荐阅读