如何根据文本的行数使容器其子级为textformfield展开? 颤抖

问题描述

我正在尝试根据大多数现代消息传递应用程序中看到的textformfield中的行数来扩展容器。我搜索高低都无济于事,并且是其中一种可能的解决方案的一部分。因此,我根据行数更改了容器的高度,但是容器不会考虑更改。进行更改后,我尝试将状态设置为set状态,但它将textformfield覆盖为一行,并还原了更改。如果您对如何编辑当前代码有任何建议,甚至可以更改我的代码以使其按预期工作,则可以在下面看到我的代码。我愿意接受所有建议!如果您需要更多信息,请在评论标记我或给我发送电子邮件isis@hanglyde.com 被引用 https://github.com/flutter/flutter/issues/21943

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),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: 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,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),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,child: Container(
                                        decoration: Boxdecoration(
                                          borderRadius: BorderRadius.circular(27.5),child: SvgPicture.string(
                      _svg_52blhh,);
  }
    }
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;

在ChatBubbleState的构建方法中;即使您在textFormField的onChanged属性中更改了chatBarHeight,也将导致chatBarHeight为62.5。

如果您想扩展容器,请先从textFormField中删除expands属性,此属性将扩展textformField以适应其在输入时不会扩展的容器,其次您不需要在内部进行计算onChanged属性。

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'),);
  }
}