如何在SingleChildScrollView底部添加固定TextField?
实现底部固定TextField不随页面滚动的解决方案
你现在的问题是把TextField嵌套在了SingleChildScrollView的Column里,所以会随着页面内容一起滚动。要让它固定在底部不滚动,可以用下面两种方案:
方案一:利用Scaffold的bottomNavigationBar属性(推荐)
Scaffold自带的bottomNavigationBar属性可以直接把组件固定在页面底部,不需要额外处理布局,是最简便的方法。修改后的代码如下:
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text( 'Thread', style: TextStyle(fontWeight: FontWeight.bold), ), ), // 滚动内容区域 body: SingleChildScrollView( controller: _scrollController, child: Column( mainAxisSize: MainAxisSize.max, children: [ // 线程列表UI ThreadRepliesTile(list: featuredThreads, isLoadingThreads:isLoadingMore), ], ), ), // 底部固定的TextField bottomNavigationBar: Column( mainAxisSize: MainAxisSize.min, children: const [ Divider(height: 0.1), Padding( padding: EdgeInsets.only(left: 16, right: 16, bottom: 8), child: TextField( decoration: InputDecoration( hintText: "Post Your Reply", enabledBorder: UnderlineInputBorder( borderSide: BorderSide(color: Colors.grey), ), focusedBorder: UnderlineInputBorder( borderSide: BorderSide(color: Colors.grey), ), suffixIcon: IconButton( padding: EdgeInsets.only(left: 8), icon: Icon(Icons.camera_alt_outlined), onPressed: () {}, )), ), ), ], ), ); }
这里把TextField部分移到了bottomNavigationBar里,并且用Column(mainAxisSize: MainAxisSize.min)包裹,避免底部栏占用过多空间。
方案二:使用Stack布局
如果不想用bottomNavigationBar,可以用Stack来实现滚动内容和底部固定组件的层叠。滚动内容占满整个屏幕,底部TextField通过Align固定在底部:
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text( 'Thread', style: TextStyle(fontWeight: FontWeight.bold), ), ), body: Stack( children: [ // 滚动内容区域 SingleChildScrollView( controller: _scrollController, child: Column( mainAxisSize: MainAxisSize.max, children: [ // 线程列表UI ThreadRepliesTile(list: featuredThreads, isLoadingThreads:isLoadingMore), // 给底部TextField留出空间,避免内容被遮挡 SizedBox(height: 80), ], ), ), // 底部固定的TextField Align( alignment: Alignment.bottomCenter, child: Column( mainAxisSize: MainAxisSize.min, children: const [ Divider(height: 0.1), Padding( padding: EdgeInsets.only(left: 16, right: 16, bottom: 8), child: TextField( decoration: InputDecoration( hintText: "Post Your Reply", enabledBorder: UnderlineInputBorder( borderSide: BorderSide(color: Colors.grey), ), focusedBorder: UnderlineInputBorder( borderSide: BorderSide(color: Colors.grey), ), suffixIcon: IconButton( padding: EdgeInsets.only(left: 8), icon: Icon(Icons.camera_alt_outlined), onPressed: () {}, )), ), ), ], ), ), ], ), ); }
注意这里要给滚动内容的底部加一个SizedBox,高度要大于等于TextField的高度,避免最后一条线程被底部的TextField遮挡。
内容的提问来源于stack exchange,提问作者Cliff Odebala Clarke
相关产品推荐
相关产品推荐

