DevBoi

[Flutter] StreamBuilder State redraw 이슈 본문

[Mobile]/[Flutter]

[Flutter] StreamBuilder State redraw 이슈

HiSmith 2024. 1. 17. 20:25
반응형

최근에 채팅 관련 모듈을 개발하면서, StreamBuilder를 사용했다.

해당 사용할때 이슈가있었는데 해당 부분에 대해서는 아래와 같다.

 

* 채팅 입력

* 채팅 내용

 

위와 같이 두개의 State를 가지는 위젯들이 있었다.

해당 채팅 내용을 입력할때, 키보드가 위로 올라가면서 화면을 가리는 이슈때문에,

해당 키보드 때문에 화면이 밀리면 다시 그려주게끔 개발을 해놨다.

 

해당 부분 때문에 StreamBuilder에서 계속 값을 재 connection을 시키려고했다.

해당 이슈로 인해, 조금만 클릭해서 progressbar가 돌았고, 나도 돌았다.

 

해결 방법은 생각보다 간단하다.

아래와 같이 stream으로 받아오는 변수를 밖으로 빼면 된다.

 

소스코드는 아래와 같다.

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:get/get.dart';
import 'package:myvalue/view/chat/widget/chat-bubble2.dart';
import 'package:myvalue/view/provider/User/global-provider.dart';
import 'package:myvalue/view/util/provider-util.dart';

final GlobalProvider globalProvider = Get.find();
class Messages2 extends StatefulWidget {
  //const Messages2({Key key,String roomId});
  final String roomId;
  const Messages2(this.roomId);
  //const Messages2({required Key key, required this.roomId}) : super(key: key);


  @override
  State<Messages2> createState() => _Messages2State();
}

class _Messages2State extends State<Messages2> {
  late Stream<QuerySnapshot<Map<String, dynamic>>> chatStream;
  @override
  void initState() {
    chatStream = FirebaseFirestore.instance.collection(widget.roomId.toString())
        .orderBy('time',descending: true)
        .snapshots();
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    // 나갈때 해당 인덱스를 늘려주기
    // FirebaseFirestore.instance.collection(roomId.toString()).snapshots().length;
    return  Expanded(
      child: StreamBuilder(
              //key: UniqueKey(),
              stream: chatStream,
              builder: (context, AsyncSnapshot<QuerySnapshot<Map<String,dynamic>>> snapshot) {
                if(snapshot.connectionState == ConnectionState.waiting){
                  return context.widget;
                }
                final chatDoc = snapshot.data!.docs;
                return ListView.builder(
                    reverse: true,
                    itemCount: chatDoc.length,
                    itemBuilder: (context,index){
                      bool changeDateYn = true;
                      if(index == chatDoc.length-1){
                        changeDateYn =true;
                      }
                      else{
                        Timestamp now = chatDoc[index]['time'];
                        Timestamp past = chatDoc[index+1]['time'];
                        DateTime time = DateTime.parse(now.toDate().toString());
                        DateTime yesterday = DateTime.parse(past.toDate().toString());
                        if(time.day != yesterday.day){
                          changeDateYn = true;
                        }
                        else{
                          changeDateYn = false;
                        }
                      }
                  return ChatBubbles2(
                      chatDoc[index]['content'],
                      chatDoc[index]['userId'] == userProvider.userInfo.id.toString(),
                      chatDoc[index]['userName'],
                      chatDoc[index]['time'],
                      changeDateYn
                  );
                });
              }
      ),
    );
  }
}

 

 

initstate를 통해서 밖의 변수에 값을 세팅해주고 

해당 세팅된 값을 참조하게끔 변경하니, 해당 이슈는 발생하지않았다.

 

간단하고 생각을 해보면 되지만 좀 처럼 해결방법이 떠오르지않았던 문제이다.

반응형