我在做一个项目。是个聊天软件我已经能够处理的大部分功能,但需要一些东西的帮助。我使用firebase作为后端,所有数据都是从firestore存储和检索的,以显示聊天中的消息。我注意到,在打开聊天时,我不会像在WhatsApp或其他聊天应用程序上正常显示的那样自动看到最后一条消息。例如,如果我键入一条新消息,我希望它是页面底部显示的最后一件事。请帮我检查一下这个。下面是我的代码:
import 'package:chat/constants.dart';
import 'package:chat/utilities/constants.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:emoji_picker/emoji_picker.dart';
import 'package:flutter/material.dart';
import 'package:chat/models/auth.dart';
import 'package:chat/models/message.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class ChatScreen extends StatefulWidget {
final AuthImplementation auth;
final VoidCallback signedOut;
ChatScreen({
this.auth,
this.signedOut,
});
@override
_ChatScreenState createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> {
bool show = false;
FocusNode focusNode = FocusNode();
final Firestore _firestore = Firestore.instance;
TextEditingController messageController = TextEditingController();
ScrollController scrollController = ScrollController();
String userName;
@override
void initState() {
super.initState();
widget.auth.getCurrentUserEmail().then((email) {
setState(() {
final String userEmail = email;
final endIndex = userEmail.indexOf("@");
userName = userEmail.substring(0, endIndex);
focusNode.addListener(() {
if (focusNode.hasFocus) {
setState(() {
show = false;
});
}
});
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: new Container(
padding: new EdgeInsets.all(8.0),
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage("assets/images/social-logo.png"),
fit: BoxFit.fill),
color: Colors.white,
borderRadius: new BorderRadius.all(new Radius.circular(80.0)),
border: new Border.all(
color: Colors.white,
width: 1.0,
),
),
),
title: Text("One Gov FX Signal Room",
style: TextStyle(
fontSize: 20,
color: Colors.white,
fontWeight: FontWeight.bold,
fontFamily: 'Spartan',
)),
backgroundColor: kPrimaryColor,
actions: <Widget>[
IconButton(
icon: FaIcon(FontAwesomeIcons.signOutAlt),
color: Colors.white,
onPressed: logOut),
],
),
backgroundColor: antiFlashWhite,
body: WillPopScope(
child: Column(
children: <Widget>[
Container(
color: Colors.white,
padding:
EdgeInsets.only(left: 10, right: 0, bottom: 10, top: 10),
child: Row(
children: [
CircleAvatar(
backgroundColor: Colors.white,
backgroundImage:
AssetImage("assets/images/social-logo.png"),
),
SizedBox(
width: 50,
),
Flexible(
child: Column(children: const <Widget>[
Text('Message From the Admins'),
Text(
'Keep your messages polite and do not abuse the channel. Try to keep your discussions within the community guidelines'),
]),
)
],
),
),
Expanded(
child: Container(
//margin: EdgeInsets.symmetric(horizontal: 5),
child: StreamBuilder<QuerySnapshot>(
stream: _firestore
.collection("messages")
.orderBy(
"timestamp",
)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData)
return Center(
child: CircularProgressIndicator(
backgroundColor: kPrimaryColor,
),
);
List<DocumentSnapshot> docs = snapshot.data.documents;
List<Widget> messages = docs
.map((doc) => Message(
user: doc.data['user'],
text: doc.data['text'],
timestamp: doc.data['timestamp'],
mine: userName == doc.data['user'],
))
.toList();
return ListView(
controller: scrollController,
children: messages,
);
}),
),
),
Container(
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Row(
children: <Widget>[
IconButton(
icon: FaIcon(
FontAwesomeIcons.smile,
color: kPrimaryColor,
),
onPressed: () {
focusNode.unfocus();
focusNode.canRequestFocus = false;
setState(() {
show = !show;
});
},
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(10),
child: TextField(
focusNode: focusNode,
style: TextStyle(
fontFamily: 'Poppins',
fontSize: 15,
),
onSubmitted: (value) => sendChat(),
controller: messageController,
scrollController: scrollController,
keyboardType: TextInputType.multiline,
textInputAction: TextInputAction.newline,
maxLines: null,
cursorColor: kPrimaryColor,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20)),
filled: true,
hintText: "Say Something. Be Nice...",
hintStyle: TextStyle(
fontFamily: 'Montserrat', fontSize: 12),
),
),
),
),
IconButton(
icon: FaIcon(
FontAwesomeIcons.file,
color: kPrimaryColor,
),
onPressed: () {
showModalBottomSheet(
backgroundColor: Colors.transparent,
context: context,
builder: (builder) => bottomsheet());
},
),
IconButton(
icon: FaIcon(
FontAwesomeIcons.paperPlane,
color: kPrimaryColor,
),
onPressed: sendChat,
),
],
),
show ? emojiSelect() : Container(),
],
),
),
],
),
onWillPop: () {
if (show) {
setState(() {
show = false;
});
} else {
Navigator.pop(context);
}
return Future.value(false);
}),
);
}
void logOut() async {
try {
await widget.auth.signOut();
widget.signedOut();
} catch (e) {
print("error :" + e.toString());
}
}
Future<void> sendChat() async {
if (messageController.text.length > 0) {
await _firestore.collection("messages").add({
'user': userName,
'text': messageController.text,
'timestamp': FieldValue.serverTimestamp(),
});
messageController.clear();
scrollController.animateTo(scrollController.position.maxScrollExtent,
duration: Duration(milliseconds: 300), curve: Curves.easeOut);
}
}
Widget bottomsheet() {
return Container(
height: 120,
width: MediaQuery.of(context).size.width,
child: Card(
margin: EdgeInsets.all(0),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 20),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
child: iconcreation(
Icons.analytics,
Colors.black,
"Analysis",
)),
SizedBox(
width: 40,
),
iconcreation(Icons.report, Colors.black, "Report User"),
SizedBox(
width: 40,
),
iconcreation(Icons.link, Colors.black, "Link")
],
),
),
),
);
}
Widget iconcreation(IconData icon, Color color, String text) {
return InkWell(
onTap: () {},
child: Column(
children: [
CircleAvatar(
backgroundColor: color,
radius: 30,
child: Icon(
icon,
size: 29,
color: Colors.white,
),
),
SizedBox(height: 5),
Text(text),
],
),
);
}
Widget emojiSelect() {
return EmojiPicker(
rows: 4,
columns: 7,
onEmojiSelected: (emoji, category) {
print(emoji);
setState(() {
messageController.text = messageController.text + emoji.emoji;
});
});
}
}
字符串
以下是该应用程序的示例图像:Screenshot of App
3条答案
按热度按时间ws51t4hk1#
在timestamp后添加
descending: true
。像
Expanded( child: Container( //margin: EdgeInsets.symmetric(horizontal: 5), child: StreamBuilder<QuerySnapshot>( stream: _firestore .collection("messages") .orderBy( "timestamp", descending: true ) .snapshots(), builder: (context, snapshot) { if (!snapshot.hasData) return Center( child: CircularProgressIndicator( backgroundColor: kPrimaryColor, ), );
zed5wv102#
试试这个:
字符串
sgtfey8w3#
添加
descending : true
字符串
也在listview.builder中添加
reverse : true
像魅力一样工作!