Flutter 聊天屏幕文本输入字段

Flutter Chat Screen Textinputfield

我已经在我的应用程序中创建了聊天。我的问题是,当有人想在 Inputfield 中输入时,Inputfield 由于 phone 键盘而上升,但我的聊天不显示 Inputfield 上方的最后一条消息。有谁知道如何解决这一问题? Chatscreen and Chatscreen with keyboard

class Chat extends StatefulWidget {
  final String chatRoomId;

  Chat({this.chatRoomId});




  @override
  _ChatState createState() => _ChatState();
}

class _ChatState extends State<Chat> {

  Stream<QuerySnapshot> chats;
  TextEditingController messageEditingController = new TextEditingController();
  Stream chatRooms;





  Widget chatMessages(){
    return StreamBuilder(
      stream: chats,
      builder: (context, snapshot){
        return snapshot.hasData ?
            ListView.builder(
                itemCount: snapshot.data.docs.length,
                itemBuilder: (context, index){
                  return MessageTile(
                    message: snapshot.data.docs[index].data()["message"],
                    sendByMe: Constants.myName == snapshot.data.docs[index].data()["sendBy"],
                    time: snapshot.data.docs[index].data()["time"],
                  );
                },
        ) : SpinKitFadingCircle(color: Colors.white, size: 20.0);
      },
    );
  }





  addMessage() {
    if (messageEditingController.text.isNotEmpty) {
      Map<String, dynamic> chatMessageMap = {
        "sendBy": Constants.myName,
        "message": messageEditingController.text,
        'time': DateTime
            .now()
            .millisecondsSinceEpoch,
      };

      DatabaseService().addMessage(widget.chatRoomId, chatMessageMap);

      setState(() {
        messageEditingController.text = "";
      });
    }
  }

  @override
  void initState() {
    DatabaseService().getChats(widget.chatRoomId).then((val) {
      setState(() {
        chats = val;
      });
    });
    super.initState();
  }

  Future<DocumentSnapshot> getUserInfo() async {
    var firebaseUser = await FirebaseAuth.instance.currentUser;
    return await FirebaseFirestore.instance.collection("SerX")
        .doc(firebaseUser.uid)
        .get();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      appBar: AppBar(
        backgroundColor: Colors.black,
        bottom: PreferredSize(
            child: Container(
              color: Colors.blue,
              height: 4.0,
            ),
            preferredSize: Size.fromHeight(0)),
        title:Text("Conversation",
          style: TextStyle(
              color: Colors.white,
              fontFamily: 'Orbitron',
              fontSize: 20.0,
              fontWeight: FontWeight.bold,
              letterSpacing: 2.2
          ),),
        leading: IconButton(icon: Icon(Icons.arrow_back ,color: Colors.blue,),onPressed: (){
          Navigator.pushReplacement(context,
              MaterialPageRoute(builder: (context) => Search()));
        },),
      ),

      body: Container(
        child: Stack(
          children: [
            Container(child: chatMessages(), height: 595),
            Container(
              alignment: Alignment.bottomCenter,
              child: Container(
                padding: EdgeInsets.symmetric(horizontal: 25, vertical: 3),
                color: Colors.white,
                child: Row(
                  children: [
                    Expanded(
                      child: TextField(
                        controller: messageEditingController,
                        style: TextStyle(
                          color: Colors.white,
                          fontFamily: 'Orbitron',
                          fontSize: 12.0,
                          fontWeight: FontWeight.bold,
                        ),
                        decoration: InputDecoration(
                          contentPadding: new EdgeInsets.symmetric(vertical: 7, horizontal: 15),
                          filled: true,
                          fillColor: Colors.black,
                          enabledBorder: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(40),
                              borderSide: BorderSide(color: Colors.blue, width: 3)
                          ),
                          focusedBorder: OutlineInputBorder(
                              borderRadius: BorderRadius.circular(40),
                              borderSide: BorderSide(color: Colors.blue, width: 3,)
                          ),
                          border: InputBorder.none,
                        ),
                      ),
                    ),
                    SizedBox(width: 20,),
                    GestureDetector(
                      onTap: () {
                        addMessage();
                      },
                      /*
                      child:Container(
                        height: 45,
                        width: 45,
                        decoration: BoxDecoration(
                            gradient: LinearGradient(
                                colors: [
                                  const Color(0xFF000000),
                                  const Color(0xFF000000),
                                ]
                            ),
                            borderRadius: BorderRadius.circular(40),
                            border: Border.all(
                                width: 2,
                                color: Colors.blue
                            )
                        ),

                       */
                          child:Icon(Icons.send, color: Colors                      ///  <--- Um den grauen script zu aktivieren hinter Icon eine klammer zu setzen!
                              .black, size: 35,),
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

}

class MessageTile extends StatelessWidget {
  final String message;
  final bool sendByMe;
  final int time;

  MessageTile({@required this.message, @required this.sendByMe, @required this.time});


  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.only(
          top: 3,
          bottom: 3,
          left: sendByMe ? 0 : 24,
          right: sendByMe ? 24 : 0),
      alignment: sendByMe ? Alignment.centerRight : Alignment.centerLeft,
      child: Container(
        margin: sendByMe
            ? EdgeInsets.only(left: 30)
            : EdgeInsets.only(right: 30),
        padding: EdgeInsets.only(
            top: 17, bottom: 17, left: 20, right: 20),
        decoration: BoxDecoration(
            borderRadius: sendByMe ? BorderRadius.only(
                topLeft: Radius.circular(9),
                topRight: Radius.circular(9),
                bottomLeft: Radius.circular(9),
            ) :
            BorderRadius.only(
                topLeft: Radius.circular(9),
                topRight: Radius.circular(9),
                bottomRight: Radius.circular(9)),
           color: sendByMe ? Colors.blue : Colors.white
        ),
        child: Text(message,
            textAlign: TextAlign.start,
            style: TextStyle(
    color: Colors.black,
    fontWeight: FontWeight.bold,
    fontFamily: 'Orbitron',
    fontSize: 9.0,),),
      ),
    );
  }
}

错误的原因是您将 chatMessages 小部件所在的 Container 的固定高度设置为 595 像素。

Container(child: chatMessages(), height: 595),

一个简单的解决方案是计算键盘的高度(参见 this question):

Container(child: chatMessages(), height: MediaQuery.of(context).size.height - 134 - MediaQuery.of(context).viewInsets.bottom),

这需要您设备的实际高度并减去 appBar、textinputfield 和键盘的高度。

但是,使用不依赖于像素计算的小部件树会更有效。特别是带键盘的部分可能会导致在较慢的设备上卡顿。