在颤振中实现 onTap

时间:2021-04-13 05:30:15

标签: flutter containers flutter-dependencies

我尝试在 ChatRoomListTile 上创建一个 onTap 函数,它将我导航到 id = chatRoomId 的聊天屏幕。很遗憾,我不知道如何提供 ID。

不幸的是,我对 Flutter 非常缺乏经验,我通过教程制作了这个应用程序......它运行良好,但我仍在学习,非常感谢!

我的 Database.dart

import 'package:cloud_firestore/cloud_firestore.dart';

import 'package:signal/helperfunctions/sharedpref_helper.dart';
class DatabaseMethods{
  Future addUserInfoToDB(String userId, Map<String, dynamic>userInfoMap)
async {
    return FirebaseFirestore.instance
    .collection("users")
    .doc(userId)
    .set(userInfoMap);
  }

  Future<Stream<QuerySnapshot>> getUserByUserName(String username) async{
    return FirebaseFirestore.instance
    .collection("users")
    .where("username", isEqualTo: username)
    .snapshots();
  }


Future addMessage(String chatRoomId, String messageId, Map messageInfoMap) async {
  return FirebaseFirestore.instance
  .collection ("chatrooms")
  .doc(chatRoomId)
  .collection("chats")
  .doc(messageId)
  .set(messageInfoMap);
  }

  updateLastMessageSend(String chatRoomId, Map lastMessageInfoMap){
    return FirebaseFirestore.instance
    .collection("chatrooms")
    .doc(chatRoomId)
    .update(lastMessageInfoMap);
  }
  
  createChatRoom(String chatRoomId, Map chatRoomInfoMap) async{
    final snapShot = await FirebaseFirestore.instance
    .collection("chatrooms")
    .doc(chatRoomId)
    .get();

    if(snapShot.exists){
      //chatroom already exists
      return true;
    }else{
      //chatroom does not exists
      return FirebaseFirestore.instance
      .collection("chatrooms")
      .doc(chatRoomId)
      .set(chatRoomInfoMap);
    }
  }


  Future<Stream<QuerySnapshot>> getChatRoomMessages(chatRoomId) async {
    return FirebaseFirestore.instance
        .collection("chatrooms")
        .doc(chatRoomId)
        .collection("chats")
        .orderBy("ts", descending: true)
        .snapshots();
  }

  // Future<Stream<QuerySnapshot>> openChatRoom(String chatRoomId) async{
  //   return FirebaseFirestore.instance
  //   .collection("chatrooms")
  //   .doc(chatRoomId)
  //   .collection("chats")
  //   .snapshots();
  // }

  Future<Stream<QuerySnapshot>> getChatRooms() async {
    String myUsername = await SharedPreferenceHelper().getUserName();
    return FirebaseFirestore.instance
      .collection("chatrooms")
      .orderBy("lastMessageSendTs", descending: true)
      .where("users",arrayContains: myUsername)
      .snapshots();
    }

  Future<QuerySnapshot> getUserInfo(String username) async {
    return await FirebaseFirestore.instance
      .collection("users")
      .where("username", isEqualTo: username)
      .get();
  }


}

和我的 home.dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:signal/helperfunctions/sharedpref_helper.dart';
import 'package:signal/services/auth.dart';
import 'package:signal/services/database.dart';
import 'package:signal/views/signin.dart';
import 'services/colorpicker.dart';

import 'chatscreen.dart';

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

  class _HomeState extends State<Home> {
    bool isSearching = false;
    String myName, myProfilePic, myUserName, myEmail, messageSentTs;
    Stream usersStream, chatRoomsStream;
    
    TextEditingController searchUsernameEditingController =
      TextEditingController();

    getMyInfoFromSharedPreference() async{
      myName = await SharedPreferenceHelper().getDisplayName();
      myProfilePic = await SharedPreferenceHelper().getUserProfileUrl();
      myUserName = await SharedPreferenceHelper().getUserName();
      myEmail = await SharedPreferenceHelper().getUserEmail(); 
      
    }


//dieser string sollte eigentlich aus sicherheitsgründen random generiert werden 
    getChatRoomIdByUsernames(String a, String b){
      if(a.substring(0,1).codeUnitAt(0) > b.substring(0,1).codeUnitAt(0)){
          return "$b\_$a";
      }else{
        return "$a\_$b";
      }
    }


  onSearchBtnClick() async {
    isSearching = true;
    setState(() {});
    usersStream = await DatabaseMethods()
      .getUserByUserName(searchUsernameEditingController.text);
    setState(() {});
  }


  Widget chatRoomsList(){
    return StreamBuilder(
      stream: chatRoomsStream,
      builder: (context, snapshot){
        return snapshot.hasData 
        ? ListView.builder(
          itemCount: snapshot.data.docs.length,
          shrinkWrap: true,
          itemBuilder: (context, index){
            DocumentSnapshot ds = snapshot.data.docs[index];
            return ChatRoomListTile(ds["lastMessage"], ds.id,myUserName);
            }) 
            : Center(child: CircularProgressIndicator());
           },
          );
        }


//                  print("this is the values we have $myUserName $username"));
//                  Chatroom ID Kontrolle ( achtung beim randomisen der CRId)
  Widget searchUserListTile({String profileUrl, name, username, email}){
    return GestureDetector(
      onTap: (){
        var chatRoomId = getChatRoomIdByUsernames(myUserName, username);
        Map<String, dynamic> chatRoomInfoMap = {
          "users" : [myUserName, username]
        };

      DatabaseMethods().createChatRoom(chatRoomId, chatRoomInfoMap);
      Navigator.push(
        context, 
        MaterialPageRoute(
          builder: (context) => ChatScreen(username, name)
        )
      );
    },
      child: Row(
     
        children: [
        ClipRRect(
          borderRadius: BorderRadius.circular(30),
            child: Image.network(
            profileUrl,
            height: 20,
            width: 20,
          ),
        ),
        SizedBox(width: 12),
        Column(
          crossAxisAlignment:  CrossAxisAlignment.start,
          children:[
          Text(name),
          Text(email),
          ],
        )
        ],
      ),
    );
  }


  Widget searchUsersList(){
    return StreamBuilder(
      stream: usersStream,
      builder: (context, snapshot){
        return snapshot.hasData 
          ? ListView.builder(
            itemCount: snapshot.data.docs.length,
            shrinkWrap: true,
            itemBuilder: (context, index){
              DocumentSnapshot ds = snapshot.data.docs[index];
              return searchUserListTile(
              profileUrl: ds["imgUrl"], 
              name: ds["name"], 
              username: ds["username"],
              email: ds["email"]
                );
            },
          ) : Center(child: CircularProgressIndicator(),);
      }
    );
  }


  getChatRooms() async {
    chatRoomsStream = await DatabaseMethods().getChatRooms();
    setState(() {});
  }


  onScreenLoaded() async {
    await getMyInfoFromSharedPreference();
    getChatRooms();
  }


  @override
  void initState() {
    onScreenLoaded();
    super.initState();
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      
      backgroundColor: Color.fromRGBO(233, 240, 244, 1),
      appBar: AppBar(
        
        title: Image.asset('assets/images/logo.png', width: 40,),
        
        elevation: 0.0,
        backgroundColor: Colors.white,
        
      actions: [
        InkWell(
          onTap: (){
            AuthMethods().signOut().then((s) {
              Navigator.pushReplacement(context, MaterialPageRoute
              (builder: (context) => SignIn()));
            });
          },
        child: Container(
        padding: EdgeInsets.symmetric(horizontal: 16),
        child: Icon(Icons.exit_to_app)),
        )
        ],
      ),
      body: Container(
        
        margin: EdgeInsets.symmetric(horizontal: 20),
        
        child: Column(
          children: [
            Row(
            
              children: [
                
                isSearching 
                
                  ? GestureDetector(
                    
                    onTap: (){
                      isSearching = false;
                      searchUsernameEditingController.text = "";
                      setState(() {});
                    },
                      child: Padding( 
                        padding: EdgeInsets.only(right: 12),
                        child: Icon(Icons.arrow_back)),
                  ) : Container(),
                Expanded(
                  child: Container( 
//                  Disable Searchbar
                    width: 0,
                    height: 0,
                    margin: EdgeInsets.symmetric(vertical: 16),
                    padding: EdgeInsets.symmetric(horizontal:16),
                    decoration: BoxDecoration
                    (border: Border.all(
                      color: Colors.black87, 
                      width: 1,
                      style: BorderStyle.solid), borderRadius: BorderRadius.circular(24)),
                  child: Row(
                    children: [
                      Expanded(
                       child: TextField(
                         
                         controller: searchUsernameEditingController,
                          decoration: InputDecoration(
                           border: InputBorder.none, hintText: "Finde einen Freund"),
                    )), 
                      GestureDetector(
                        onTap:(){
                            if(searchUsernameEditingController.text != ""){
                              onSearchBtnClick();
                            }
                          },
//                     Disable Search Icon
//                     child: Icon(Icons.search),
                           
                    )
                  ],
                ),
              ),
            ) 
          ]
           ),
          isSearching ? searchUsersList() : chatRoomsList()
         ],
        ),
       ),
    );
  }
}


class ChatRoomListTile extends StatefulWidget {
  final String lastMessage, chatRoomId, myUsername;
  ChatRoomListTile(this.lastMessage, this.chatRoomId, this.myUsername);
  
  @override
  _ChatRoomListTileState createState() => _ChatRoomListTileState();
}

class _ChatRoomListTileState extends State<ChatRoomListTile> {

  String profilePicUrl ="", name="", username="";

  getThisUserInfo() async {
    username = widget.chatRoomId.replaceAll(widget.myUsername, "").replaceAll("_", "");
    QuerySnapshot querySnapshot = await DatabaseMethods().getUserInfo(username);
    name = "${querySnapshot.docs[0]["name"]}";
    profilePicUrl = "${querySnapshot.docs[0]["imgUrl"]}";
   setState(() {});
  }

  @override
  void initState() {
      getThisUserInfo();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    
    
    return Container(
                   margin: EdgeInsets.symmetric(vertical: 2, horizontal: 0,),
                    padding: EdgeInsets.symmetric(horizontal:12,vertical: 20,),
                    decoration: BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.circular(8),
 
                  ),
                            
      child: Row(
        
       children: [
        ClipRRect(
          borderRadius: BorderRadius.circular(8),
          
            child: Image.network(
              profilePicUrl, 
              height: 35, 
              width: 35,
            ),
        ),
        SizedBox(width: 15),
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                 Text(
                    name,
                      style: TextStyle(
                        fontSize: 14,
                        fontFamily: 'Roboto',
                        color: Color.fromRGBO(57, 59, 85, 0.8),
                        fontWeight: FontWeight.w500,
                        ),
                ),
                SizedBox(height: 5),
                 
              Container(
                  
                  width: (MediaQuery.of(context).size.width) - 150,
                  child: Text(
                    widget.lastMessage,
                      style: new TextStyle(
                        fontSize: 13.0,
                        fontFamily: 'Roboto',
                        color: Color.fromRGBO(171, 183, 201, 1),
                        fontWeight: FontWeight.w400,
                      ),
                      overflow: TextOverflow.ellipsis,
                      maxLines: 1,
                    ),
                    
                ),
               
              ],
            )
            
        ],
      ),
       );
  }
}

2 个答案:

答案 0 :(得分:1)

您可以将 id 作为构造函数从 listTile 传递, Navigator.of(context).push.... ChatScreen(id: chatRoomId) 如此,在 ChatScreen 中,您可以像这样接收它

class ChatScreenextends StatefulWidget {
final String id;
ChatScreen({requried this.id});
  @override
  _ChatScreenState createState() => _ChatScreenState ();
}

class _ChatScreenState extends State<ChatScreen> {

如果它是一个无状态的 Widget 类,你可以直接访问 id 作为 id,如果它是一个有状态的 Widget 则 widget.id

另一种方法是作为 Navigator 参数传递,您可以查看文档以获取更多信息 Flutter Docs

答案 1 :(得分:0)

您好,非常感谢您抽出宝贵时间……我尝试实施它,但不幸的是我遇到了错误。在这里,我添加到 home.dart 的 GestureDetector ::: 我也尝试将 id: chatRoomId 更改为 this.Id 或只是 chatRoomId .. 但它始终带有下划线并出错:

  Widget build(BuildContext context) {  
    return GestureDetector(
      onTap: () {
      Navigator.push(context,
      MaterialPageRoute(builder: (context) => ChatScreen(id: chatRoomId)));
          },
          child: Container(
                     margin: EdgeInsets.symmetric(vertical: 2, horizontal: 0,),
                      padding: EdgeInsets.symmetric(horizontal:12,vertical: 20,),
                      decoration: BoxDecoration(
                        color: Colors.white,
                        borderRadius: BorderRadius.circular(8),
 
                    ),

这里是 chatscreen.dart 的更新


  class ChatScreen extends StatefulWidget {
    final String chatWidthUsername, name, id;
    ChatScreen(this.chatWidthUsername, this.name, {this.id});
    @override
    _ChatScreenState createState() => _ChatScreenState();
  }



  class _ChatScreenState extends State<ChatScreen> {

    String chatRoomId, messageId = "";
    Stream messageStream;
    String myName, myProfilePic, myUserName, myEmail;
    TextEditingController messageTextEditingController = TextEditingController();

再次感谢! 问候 亚历克斯