簡體   English   中英

如何在 flutter 中正確構建屏幕

[英]How to build screens properly in flutter

我是 flutter 的新手,我需要幫助以正確的順序渲染屏幕。

我正在創建一個聊天應用程序,以前有一個聊天概述屏幕,如果有人點擊“聊天室磁貼”,他/她會轉到該特定聊天室的屏幕。 從內部,如果使用 Navigator.pop() 按下后退按鈕,他/她將再次登陸聊天概覽屏幕。

直到現在一切都運行良好。

但是在添加本地通知后,當用戶從通知欄單擊通知后直接進入特定聊天室的屏幕時,聊天室屏幕中帶有 navigator.pop 的后退按鈕不起作用。 我還嘗試使用 Navigator.pushReplacementNamed() 在單擊后退按鈕時呈現聊天概述屏幕,但在這種情況下不會出現應用程序的底部標簽欄。

 class ChatOverviewScreen extends StatefulWidget { const ChatOverviewScreen({Key? key}): super(key: key); @override State<ChatOverviewScreen> createState() => _ChatOverviewScreenState(); } class _ChatOverviewScreenState extends State<ChatOverviewScreen> { @override void initState() { super.initState(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text( Constants.appName, style: TextStyle( color: Constants.textPrimary, ), ), actions: [ GestureDetector( onTap: () { Session().clearSession(); Navigator.popAndPushNamed(context, Routes.authHomeScreen); }, child: Container( margin: const EdgeInsets.symmetric(horizontal: 15), child: Center( child: Text( 'Logout', style: TextStyle( color: Theme.of(context).primaryColor, fontSize: 15), ), ), ), ), ], backgroundColor: Constants.backgroundPrimary, ), body: SafeArea( child: Column( children: [ const ChatFetchingIndicator(), Expanded( child: BlocBuilder<ChatBloc, ChatState>( builder: (context, state) { return Container( constraints: BoxConstraints( minHeight: MediaQuery.of(context).size.height), child: ListView.builder( shrinkWrap: true, itemBuilder: (context, index) { ChatRoomWithLastChat chatRoomWithLastChat = state.chatRooms[index]; ID friendId = chatRoomWithLastChat.friendId; FullName friendName = chatRoomWithLastChat.friendName; SecureURL? friendAvatar = chatRoomWithLastChat.friendAvatar; return ChatTile( friendName: friendName, lastText: chatRoomWithLastChat.lastChat?.message?? "", lastMessageTime: chatRoomWithLastChat.lastChatTime, friendId: friendId, lastChatStatus: chatRoomWithLastChat.lastChat?.status?? ChatStatus.pending, isLastTextMine: chatRoomWithLastChat.lastChat?.senderId == friendId? false: true, friendAvatar: friendAvatar, unreadCount: chatRoomWithLastChat.unreadCount, ); }, itemCount: state.chatRooms.length, ), ); }, ), ), ], ), ), ); } }

聊天屏幕

 class ChatScreen extends StatefulWidget { final ID friendId; final SecureURL friendAvatar; final FullName friendName; const ChatScreen({ Key? key, required this.friendId, required this.friendAvatar, required this.friendName, }): super(key: key); @override State<ChatScreen> createState() => _ChatScreenState(); } class _ChatScreenState extends State<ChatScreen> { final TextEditingController _textEditingController = TextEditingController(); final ScrollController _scrollController = ScrollController(); @override Widget build(BuildContext context) { Navigator.of(context).p return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).primaryColor, leading: IconButton( icon: const Icon(Icons.arrow_back_ios_new), onPressed: () { BlocProvider.of<ChatBloc>(context).add(const ResetActiveChatRoom()); Navigator.pop(context); }, ), title: Row( children: [ CircleAvatar( backgroundColor: Theme.of(context).backgroundColor, backgroundImage: NetworkImage(widget.friendAvatar.toString()), ), const SizedBox( width: 15, ), Text(widget.friendName.value.getOrElse(() => "Unknown User")), ], ), actions: const [ Icon(Icons.more_vert_sharp), SizedBox( width: 10.0, ) ], ), body: Column( children: [ ChatsContainer( friendId: widget.friendId, friendName: widget.friendName, scrollController: _scrollController, ), ChatTextField( sendMessage: sendMessage, scrollController: _scrollController, controller: _textEditingController, receiverId: widget.friendId, ), ], ), ); } @override void dispose() { _scrollController.dispose(); _textEditingController.dispose(); super.dispose(); } void sendMessage(ID receiverId) { try { if (_textEditingController.text.isNotEmpty) { SendChatInput sendChatInput = SendChatInput.of( senderId: context.read<UserCubit>().state.user.id, receiverId: receiverId, message: _textEditingController.text); BlocProvider.of<ChatBloc>(context).add(SendChat(sendChatInput)); _textEditingController.clear(); // _scrollController.animateTo( // _scrollController.position.maxScrollExtent, // duration: const Duration(milliseconds: 300), // curve: Curves.easeInExpo, // ); } } catch (e) { throw ErrorDescription(e.toString()); } } }

在 ChatOverview 屏幕中創建數據類型為 boolean 的參數 & 當用戶打開通知而不是直接打開聊天屏幕時,

  1. 呼叫聊天概述屏幕並傳遞 boolean 參數 - 真。
  2. 當 boolean 為真時,從概覽屏幕調用聊天屏幕。
class ChatOverviewScreen extends StatefulWidget {
  final bool isFromNotification;
  const ChatOverviewScreen({Key? key,this.isFromNotification = false}) : super(key: key);

  @override
  State<ChatOverviewScreen> createState() => _ChatOverviewScreenState();
}

class _ChatOverviewScreenState extends State<ChatOverviewScreen> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
  
  if(widget.isFromNotification){
  // navigate to Chat Screen
  }
  
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          Constants.appName,
          style: TextStyle(
            color: Constants.textPrimary,
          ),
        ),
        actions: [
          GestureDetector(
            onTap: () {
              Session().clearSession();
              Navigator.popAndPushNamed(context, Routes.authHomeScreen);
            },
            child: Container(
              margin: const EdgeInsets.symmetric(horizontal: 15),
              child: Center(
                child: Text(
                  'Logout',
                  style: TextStyle(
                      color: Theme.of(context).primaryColor, fontSize: 15),
                ),
              ),
            ),
          ),
        ],
        backgroundColor: Constants.backgroundPrimary,
      ),
      body: SafeArea(
        child: Column(
          children: [
            const ChatFetchingIndicator(),
            Expanded(
              child: BlocBuilder<ChatBloc, ChatState>(
                builder: (context, state) {
                  return Container(
                    constraints: BoxConstraints(
                        minHeight: MediaQuery.of(context).size.height),
                    child: ListView.builder(
                      shrinkWrap: true,
                      itemBuilder: (context, index) {
                        ChatRoomWithLastChat chatRoomWithLastChat =
                            state.chatRooms[index];
                        ID friendId = chatRoomWithLastChat.friendId;

                        FullName friendName = chatRoomWithLastChat.friendName;

                        SecureURL? friendAvatar =
                            chatRoomWithLastChat.friendAvatar;

                        return ChatTile(
                          friendName: friendName,
                          lastText:
                              chatRoomWithLastChat.lastChat?.message ?? "",
                          lastMessageTime: chatRoomWithLastChat.lastChatTime,
                          friendId: friendId,
                          lastChatStatus:
                              chatRoomWithLastChat.lastChat?.status ??
                                  ChatStatus.pending,
                          isLastTextMine:
                              chatRoomWithLastChat.lastChat?.senderId ==
                                      friendId
                                  ? false
                                  : true,
                          friendAvatar: friendAvatar,
                          unreadCount: chatRoomWithLastChat.unreadCount,
                        );
                      },
                      itemCount: state.chatRooms.length,
                    ),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

通過這樣做,您可以直接從聊天屏幕中彈出,無需在返回按鈕上使用 Navigator.pushReplacementNamed()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM