Flutter 如何使容器(其子容器是textformfield)根据文本行数展开?(颤振)
我正试图使容器根据textformfield中的行数展开,正如您在大多数现代消息传递应用程序中看到的那样。我到处寻找,但毫无结果,我也在寻找一个可能的解决办法。因此,我有容器高度的变化,基于线的数量部分,但容器将不尊重这些变化。我尝试在进行更改后设置一个状态,但它将textformfield改写为一行,并恢复了更改。我的代码可以在下面看到,如果你对如何编辑我的当前代码有任何建议,甚至可以更改我的代码使其按预期工作,我愿意接受所有建议!如果您需要更多信息,请在评论或电子邮件中为我添加标签isis@hanglyde.com 参考Flutter 如何使容器(其子容器是textformfield)根据文本行数展开?(颤振),flutter,dart,containers,chat,textformfield,Flutter,Dart,Containers,Chat,Textformfield,我正试图使容器根据textformfield中的行数展开,正如您在大多数现代消息传递应用程序中看到的那样。我到处寻找,但毫无结果,我也在寻找一个可能的解决办法。因此,我有容器高度的变化,基于线的数量部分,但容器将不尊重这些变化。我尝试在进行更改后设置一个状态,但它将textformfield改写为一行,并恢复了更改。我的代码可以在下面看到,如果你对如何编辑我的当前代码有任何建议,甚至可以更改我的代码使其按预期工作,我愿意接受所有建议!如果您需要更多信息,请在评论或电子邮件中为我添加标签isis@
将'dart:ui'导入为ui;
进口“包装:颤振/材料.省道”;
导入“package:flatter/rendering.dart”;
导入“package:photogroup2/recurringwidgets/ombrebackground.dart”;
导入“recurringwidgets/size_config.dart”;
//导入“包:颤振聊天吧/颤振聊天吧.dart”;
导入“chat/chatbar.dart”;
///最大盒子尺寸W 291 H 294
///最小盒子尺寸W 150 H 52
导入“expandedImage.dart”;
类ChatDemo扩展StatefulWidget{
//最终用户;
//ChatDemo({this.user});
@凌驾
_ChatDemoState createState()=>\u ChatDemoState();
}
类\u ChatDemoState使用RouteAware扩展状态{
双初始高度=ChatBubbleState.chatBarHeight;
@凌驾
小部件构建(构建上下文){
打印(“聊天栏高度$chatbusblestate.chatBarHeight”);
如果(chatbusblestate.updated){
打印(“聊天栏高度$chatbusblestate.chatBarHeight”);
}
返回脚手架(
resizeToAvoidBottomInset:false,
//resizeToAvoidBottomPadding:true,
正文:安全区(
底部:错误,
上图:错,
child://列(
//mainAxisAlignment:mainAxisAlignment.spaceAround,
//儿童:[
堆叠(
儿童:[
ombreBackground(),
定位(
底部:MediaQuery.of(context).viewInsets.bottom,
孩子:填充(
填充:仅限边缘组(顶部:750*SizeConfig.高度比),
子:堆栈(
儿童:[
定位(
顶部:22.5*SizeConfig.高度比,
底部:0,
孩子:ClipRRect(
borderRadius:仅限borderRadius(
左上:半径。圆形(32.0),
右上角:半径。圆形(32.0),
),
孩子:ClipRect(
//clipBehavior:Clip.antiAlias,
孩子:背投滤波器(
过滤器:ui.ImageFilter.blur(
sigmaX:20,
5月20日,
),
子:Transform.translate(
偏移量:偏移量(0,20*SizeConfig.heightRatio),
子:容器(
身高:42,
宽度:SizeConfig.screenWidth,
装饰:盒子装饰(
borderRadius:仅限borderRadius(
左上:半径。圆形(32.0),
右上角:半径。圆形(32.0),
),
颜色:
常量颜色(0x00000000)。不透明度(0.00),
),
),
),
),
),
),
),
转换(
偏移量:偏移量(0,-5*SizeConfig.heightRatio),
孩子:聊天吧(
//地址:20,
阿瓦塔拉迪乌斯:22,
化身颜色:颜色(0xFFFFFF),
高度:chatbusblestate.chatBarHeight,//62.5,//OG 60
宽度:SizeConfig.screenWidth,//OG 370
颜色:颜色(0x00000000),
第一个孩子:chatbuble(),
secondChild:secondChild(),
),
),
],
),
),
),
],
),
),
);
}
}
类chatbuble扩展StatefulWidget{
常数聊天泡泡({
关键点,
}):super(key:key);
@凌驾
ChatBubbleState createState()=>ChatBubbleState();
}
类ChatBubbleState扩展了状态{
静态双高;
静态布尔更新=真;
@凌驾
小部件构建(构建上下文){
final TextEditingController myController=TextEditingController();
int numLines=1;
int charLength=0;
chatBarHeight=62.5;
//= 52.5;//52.5;
int lastIndexNewLine=0;
//打印($numLines之前);
//建立标准
返回填充(
填充:仅限常量边集(底部:5),
子:容器(
//页边距:仅限边集(顶部:13,底部:5),
//颜色:颜色,蓝色,
/*约束:BoxConstraints(
最大高度:176,
),*/
//身高:身高,
身高:身高,
宽度:310.0*SizeConfig.widthRatio,
装饰:盒子装饰(
边界半径:边界半径。圆形(27.5),
//颜色:颜色,蓝色,
颜色:常量颜色(0xFFFFFF),
boxShadow:[
箱形阴影(
颜色:常量颜色(0x29000000),
偏移量:偏移量(3,3),
半径:6,
),
],
),
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:photosgroup2/recurringwidgets/ombrebackground.dart';
import 'recurringwidgets/size_config.dart';
//import 'package:flutter_chat_bar/flutter_chat_bar.dart';
import 'chat/chatbar.dart';
///MAX BOX SIZE W 291 H 294
///MIN BOX SIZE W 150 H 52
import 'expandedImage.dart';
class ChatDemo extends StatefulWidget {
//final User user;
//ChatDemo({this.user});
@override
_ChatDemoState createState() => _ChatDemoState();
}
class _ChatDemoState extends State<ChatDemo> with RouteAware {
double intialHeight = ChatBubbleState.chatBarHeight;
@override
Widget build(BuildContext context) {
print('Chat Bar Height $ChatBubbleState.chatBarHeight ');
if(ChatBubbleState.updated){
print('Chat Bar Height $ChatBubbleState.chatBarHeight ');
}
return Scaffold(
resizeToAvoidBottomInset: false,
//resizeToAvoidBottomPadding: true,
body: SafeArea(
bottom: false,
top: false,
child: //Column(
//mainAxisAlignment: MainAxisAlignment.spaceAround,
//children: <Widget>[
Stack(
children: <Widget>[
ombreBackground(),
Positioned(
bottom: MediaQuery.of(context).viewInsets.bottom,
child: Padding(
padding: EdgeInsets.only(top: 750 * SizeConfig.heightRatio),
child: Stack(
children: [
Positioned(
top: 22.5 * SizeConfig.heightRatio,
bottom: 0,
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(32.0),
topRight: Radius.circular(32.0),
),
child: ClipRect(
//clipBehavior: Clip.antiAlias,
child: BackdropFilter(
filter: ui.ImageFilter.blur(
sigmaX: 20,
sigmaY: 20,
),
child: Transform.translate(
offset: Offset(0, 20 * SizeConfig.heightRatio),
child: Container(
height: 42,
width: SizeConfig.screenWidth,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(32.0),
topRight: Radius.circular(32.0),
),
color:
const Color(0x00000000).withOpacity(0.00),
),
),
),
),
),
),
),
Transform.translate(
offset: Offset(0, -5 * SizeConfig.heightRatio),
child: FlutterChatBar(
//addIconSize: 20,
avatarRadius: 22,
avatarColor: Color(0xffffffff),
height: ChatBubbleState.chatBarHeight,//62.5, // OG 60
width: SizeConfig.screenWidth, // OG 370
color: Color(0x00000000),
firstChild: ChatBubble(),
secondChild: SecondChild(),
),
),
],
),
),
),
],
),
),
);
}
}
class ChatBubble extends StatefulWidget {
const ChatBubble({
Key key,
}) : super(key: key);
@override
ChatBubbleState createState() => ChatBubbleState();
}
class ChatBubbleState extends State<ChatBubble> {
static double chatBarHeight;
static bool updated = true;
@override
Widget build(BuildContext context) {
final TextEditingController myController = TextEditingController();
int numLines = 1;
int charLength = 0;
chatBarHeight = 62.5;
//= 52.5;//52.5;
int lastIndexNewLine = 0;
//print('before $numLines');
//builds the bar
return Padding(
padding: const EdgeInsets.only(bottom: 5),
child: Container(
//margin: EdgeInsets.only(top:13,bottom: 5),
//color: Colors.blue,
/*constraints: BoxConstraints(
maxHeight: 176,
),*/
//height: chatBarHeight,
height: chatBarHeight,
width: 310.0 * SizeConfig.widthRatio,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(27.5),
//color: Colors.blue,
color: const Color(0xffffffff),
boxShadow: [
BoxShadow(
color: const Color(0x29000000),
offset: Offset(3, 3),
blurRadius: 6,
),
],
),
child:
/*Padding(
padding: EdgeInsets.only(
left: 12 * SizeConfig.widthRatio,
right: 12 * SizeConfig.widthRatio,
top: 13 * SizeConfig.heightRatio,
bottom: 5 * SizeConfig.heightRatio),
child:*/
TextFormField(
expands: true,
textAlign: TextAlign.start,
style: TextStyle(
fontSize: 17 * SizeConfig.textMultiplier,
color: const Color(0xd9343f4b),
fontFamily: 'Lato'),
//textAlign: TextAlign.left,
maxLines: null,
minLines: null,
textCapitalization: TextCapitalization.sentences,
onChanged: (String e) {
//String partial =e;
charLength = e.length;
numLines = '\n'.allMatches(e).length + 1;
if (e.contains('\n')) {
lastIndexNewLine = e.indexOf('\n');
e = e.substring(lastIndexNewLine);
charLength = e.length - 1;
}
if (charLength > 35) {
numLines++;
}
if (numLines == 1) {
// chatBarHeight = 52.5;
}
if (numLines >= 2) {
print('I have 2 lines.');
chatBarHeight = 110;
updated = true;
print(chatBarHeight);
print('uPDATED $updated');
}
print('after $numLines');
},
controller: myController,
decoration: InputDecoration.collapsed(
hintStyle: TextStyle(
color: Color(0x80343f4b),
fontFamily: 'Lato',
fontSize: 15 * SizeConfig.textMultiplier,
//color: const Color(0xd9343f4b),
),
// hintStyle: ,
hintText: 'Enter Comment'),
),
),
// ), //Padding
//),
);
}
}
class SecondChild extends StatelessWidget {
const SecondChild({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Transform.translate(
offset:
Offset(12.5 * SizeConfig.widthRatio, -2.5 * SizeConfig.heightRatio),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
],
),
);
}
}
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class FlutterChatBar extends StatelessWidget {
//Height of Chat Bar widget.
final double height;
//Width of chat bar widget.
final double width;
//Color of chat bar widget.
final Color color;
//Initial child which is to be displayed inside chat bar widget.
//Ex- Message Container which is displayed (Can be TextField also)
final Widget firstChild;
//Child which comes after animation (when we tap on add Icon button)
//Ex - 3 Icons which are displayed
final Widget secondChild;
//Color of add Icon by default it is white.
final Color addIconColor;
//Color of Circle avatar which has a child of Add Icon , by default color is white30
final Color avatarColor;
//Radius of circle avatar , by default it is 30.0
final double avatarRadius;
//Size of add Icon , by default it is 30.0
final double addIconSize;
FlutterChatBar(
{
@required this.height,
@required this.width,
@required this.color,
@required this.firstChild,
@required this.secondChild,
this.addIconColor = Colors.white,
this.avatarColor = Colors.white30,
this.avatarRadius = 43.0,
this.addIconSize = 43.0
}
);
@override
Widget build(BuildContext context) {
return Container(
height: height,
width: width,
decoration: BoxDecoration(
//borderRadius: BorderRadius.circular(27.5),
color: color),
child: ContentWidget(
firstChild: firstChild,
secondChild: secondChild,
color: color,
addIconColor: addIconColor,
addIconSize: addIconSize,
avatarRadius: avatarRadius,
avatarColor: avatarColor,
),
);
}
}
class ContentWidget extends StatefulWidget {
final Widget firstChild;
final Widget secondChild;
final Color color;
final Color addIconColor;
final Color avatarColor;
final double addIconSize;
final double avatarRadius;
ContentWidget(
{this.firstChild,
this.secondChild,
this.color,
this.addIconColor,
this.avatarColor,
this.addIconSize,
this.avatarRadius});
@override
_ContentWidgetState createState() => _ContentWidgetState();
}
class _ContentWidgetState extends State<ContentWidget>
with SingleTickerProviderStateMixin {
AnimationController _controller;
//Animation for firstChild (Ex- Message container)
Animation<double> _firstChildAnimation;
//Animation for secondChild (Ex- 3 Icons in a row)
Animation<double> _secondChildAnimation;
//Animation for add Icon
Animation<double> _iconAnimation;
@override
void initState() {
super.initState();
_controller =
AnimationController(duration: Duration(milliseconds: 500), vsync: this)
..addListener(() {
setState(() {});
});
_firstChildAnimation = Tween(begin: pi / 4, end: 0.0).animate(CurvedAnimation(
parent: _controller,
curve: Curves.easeOut,
reverseCurve: Curves.easeIn));
_secondChildAnimation = Tween(begin: 0.0, end: pi / 4).animate(CurvedAnimation(
parent: _controller,
curve: Curves.easeIn,
reverseCurve: Curves.easeOut));
_iconAnimation = Tween(begin: 0.0, end: pi / 4).animate(CurvedAnimation(
parent: _controller,
curve: Curves.easeOut,
reverseCurve: Curves.easeIn));
}
@override
void dispose() {
super.dispose();
_controller.dispose();
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
/*Padding(
//padding: const EdgeInsets.all(4.0),
child:*/
Flexible(
fit: FlexFit.loose,
flex: 1,
child: GestureDetector(
onTap: () {
if (_controller.status == AnimationStatus.completed) {
_controller.reverse();
} else {
_controller.forward();
}
},
child: Transform.translate(
offset: Offset(20,-3), //15
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(27.5),
boxShadow: [
BoxShadow(
color: const Color(0x29000000),
offset: Offset(3, 3),
blurRadius: 6,
),
],
),
child: CircleAvatar( ///radius 22
backgroundColor: widget.avatarColor,
radius: widget.avatarRadius,
child: Transform.rotate(
angle: _iconAnimation.value,
child: SvgPicture.string(
_svg_nznkw8,
allowDrawingOutsideViewBox: true,
fit: BoxFit.fill,
),),
),
),
),
),
),
//),
Flexible(
flex:7,
child: Stack(
children: <Widget>[
Transform.scale(
scale: _firstChildAnimation.value,
child: widget.firstChild,
),
Transform.scale(
scale: _secondChildAnimation.value,
child: widget.secondChild,
)
],
),
),
Flexible
(
flex: 1,
fit: FlexFit.loose,
child: Transform.translate(
offset: Offset(-20,-3),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(27.5),
boxShadow: [
BoxShadow(
color: const Color(0x29000000),
offset: Offset(3, 3),
blurRadius: 6,
),
],
),
child: CircleAvatar( ///radius 22
backgroundColor: widget.avatarColor,
radius: widget.avatarRadius,
child: SvgPicture.string(
_svg_52blhh,
allowDrawingOutsideViewBox: true,
fit: BoxFit.fill,
),),
),
),
),
],
);
}
}
const String _svg_52blhh = //send
'<svg viewBox="332.0 762.0 20.0 20.0" ><path transform="translate(332.0, 762.0)" d="M 18.59535026550293 0.1261749565601349 L 0.4879408478736877 10.56938934326172 C -0.2191661894321442 10.97555732727051 -0.1293128132820129 11.95973491668701 0.5738875865936279 12.25654983520508 L 4.726676464080811 13.99838733673096 L 15.95053577423096 4.109749794006348 C 16.16540145874023 3.918381690979004 16.47012329101562 4.211291790008545 16.28650856018066 4.433903217315674 L 6.875344276428223 15.89644432067871 L 6.875344276428223 19.04034423828125 C 6.875344276428223 19.96203422546387 7.988744735717773 20.32524108886719 8.535677909851074 19.65740776062012 L 11.01641273498535 16.63848304748535 L 15.88412189483643 18.6771354675293 C 16.43886947631836 18.91146278381348 17.07174873352051 18.56387710571289 17.1733226776123 17.96634101867676 L 19.98612403869629 1.094730377197266 C 20.11895179748535 0.3058263659477234 19.27120399475098 -0.2643715739250183 18.59535026550293 0.1261749565601349 Z" fill="#343f4b" stroke="none" stroke-width="1" stroke-miterlimit="10" stroke-linecap="butt" /></svg>';
const String _svg_nznkw8 =
'<svg viewBox="24.0 762.0 22.0 22.0" ><path transform="translate(24.0, 762.0)" d="M 20.4285717010498 8.642857551574707 L 13.35714244842529 8.642857551574707 L 13.35714244842529 1.571428537368774 C 13.35714244842529 0.703705370426178 12.65343761444092 0 11.7857141494751 0 L 10.2142858505249 0 C 9.346562385559082 0 8.642857551574707 0.703705370426178 8.642857551574707 1.571428537368774 L 8.642857551574707 8.642857551574707 L 1.571428537368774 8.642857551574707 C 0.703705370426178 8.642857551574707 0 9.346562385559082 0 10.2142858505249 L 0 11.7857141494751 C 0 12.65343761444092 0.703705370426178 13.35714244842529 1.571428537368774 13.35714244842529 L 8.642857551574707 13.35714244842529 L 8.642857551574707 20.4285717010498 C 8.642857551574707 21.29629516601562 9.346562385559082 22 10.2142858505249 22 L 11.7857141494751 22 C 12.65343761444092 22 13.35714244842529 21.29629516601562 13.35714244842529 20.4285717010498 L 13.35714244842529 13.35714244842529 L 20.4285717010498 13.35714244842529 C 21.29629516601562 13.35714244842529 22 12.65343761444092 22 11.7857141494751 L 22 10.2142858505249 C 22 9.346562385559082 21.29629516601562 8.642857551574707 20.4285717010498 8.642857551574707 Z" fill="#343f4b" stroke="none" stroke-width="1" stroke-miterlimit="10" stroke-linecap="butt" /></svg>';
final TextEditingController myController = TextEditingController();
int numLines = 1;
int charLength = 0;
chatBarHeight = 62.5;
//= 52.5;//52.5;
int lastIndexNewLine = 0;
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home: ExpandingText(),
));
}
class ExpandingText extends StatefulWidget {
_ExpandingText createState() => _ExpandingText();
}
class _ExpandingText extends State<ExpandingText> {
TextEditingController myController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Container(
width: 310.0,
decoration: BoxDecoration(
color: const Color(0xffffffff),
boxShadow: [
BoxShadow(
color: const Color(0x29000000),
offset: Offset(3, 3),
blurRadius: 6,
),
],
),
child: TextFormField(
textAlign: TextAlign.start,
style: TextStyle(
fontSize: 17,
color: const Color(0xd9343f4b),
fontFamily: 'Lato'),
maxLines: null,
textCapitalization: TextCapitalization.sentences,
controller: myController,
decoration: InputDecoration(
hintStyle: TextStyle(
color: Color(0x80343f4b),
fontFamily: 'Lato',
fontSize: 15,
),
// hintStyle: ,
hintText: 'Enter Comment'),
),
),
),
);
}
}