카테고리 없음

[Flutter] 채팅 화면 구현하기 (채팅 Input TextField 만들기)

보틀펌킨 2022. 7. 10. 13:43
반응형

 

채팅 Input TextField 만들기

 

채팅을 구현하는 서비스를 제작중에 있다보니, 채팅 UI를 그리게 되었고, 하다보니 몇가지 놓치는 부분에 대해서 추후에는 Socket IO와 연동해서 단순 채팅 개발구현까지 하나하나 진행 해 보려고 합니다.

이번엔 첫번째로 채팅 Input textfield를 구현해보려고 합니다.

Align(
          alignment: Alignment.bottomCenter,
              child: Container(
                color: Colors.white,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                    Container(
                      color: Colors.grey,
                      height: 1,
                    ),
                    Padding(
                      padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
                      child: Container(
                        //height: 48,
                        decoration: BoxDecoration(
                          border: Border.all(color: Colors.grey),
                          borderRadius: BorderRadius.circular(30),
                        ),
                        child: Row(
                          children: [
                            SizedBox(
                              width: SizeConfig().screenWidth - 80,
                              child: SingleChildScrollView(
                                controller: chatInputScrollController,
                                child: Scrollbar(
                                  controller: chatInputScrollController,
                                  child: ConstrainedBox(
                                    constraints:
                                        const BoxConstraints(maxHeight: 300),
                                    child: Padding(
                                      padding:
                                          EdgeInsets.symmetric(horizontal: 12),
                                      child: TextFormField(
                                        onChanged: (value) {},
                                        decoration: InputDecoration(
                                          hintText: '메세지 보내기',
 
                                          border: InputBorder
                                              .none,
                                        ),
                                      ),
                                    ),
                                  ),
                                ),
                              ),
                            ),
                            GestureDetector(onTap: () {}, child: Icon(Icons.send))
                          ],
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            )

저는 이렇게 간단하게 구현해보았는데요? 구현하다보니 한가지 놓치고 있었던 점을 발견하게 되었습니다. 혹시 어떤건지 감이 좀 잡히시나요?

 

 

네 맞습니다 ㅠㅠ 계속 옆으로 쭉~~ 밀려서 써지는게 보이시죠? 이렇게 되면 아무래도 유저가 사용하기에 불편한점이 있을거에요. 그래서 TextField가 점점 커져서 유저가 채팅을 칠때 불편함을 줄일 수 있는 UI를 만들어 보겠습니다.

 

 

1. constraintBox에 maxHeight 300으로 설정

ConstrainedBox(
      constraints: BoxConstraints(
      maxHeight: 300
),

 

2. TextFormField의 maxLines, minLines를 4,1로 설정

TextFormField(
 maxLines: 4,
 minLines: 1,
...
)

 

 

 

여기까지만 진행하셔도 아주 훌륭한 채팅용 텍스트 필드가 완성이 되는데요? 하지만 ScrollBar까지 같이 있다면, 더 좋은 UI의 앱을 만들 수 있지 않을까요?

 

 

 

3. 기호에 따라 ScrollBar를 추가

ScrollBar

*Error 1

The following assertion was thrown while notifying status listeners for AnimationController:
The Scrollbar's ScrollController has no ScrollPosition attached.

A Scrollbar cannot be painted without a ScrollPosition. 

The Scrollbar attempted to use the PrimaryScrollController. This ScrollController should be associated with the ScrollView that the Scrollbar is being applied to. A ScrollView with an Axis.vertical ScrollDirection will automatically use the PrimaryScrollController if the user has not provided a ScrollController, but a ScrollDirection of Axis.horizontal will not. To use the PrimaryScrollController explicitly, set ScrollView.primary to true for the Scrollable widget.

⇒ 너 ScrollController 추가해야되

⇒ Stateful Widget으로 변경 후, ScrollController를 ScrollBar에 추가

*Error2

The following assertion was thrown while notifying status listeners for AnimationController:
The Scrollbar's ScrollController has no ScrollPosition attached.

A Scrollbar cannot be painted without a ScrollPosition. 

The Scrollbar attempted to use the provided ScrollController. This ScrollController should be associated with the ScrollView that the Scrollbar is being applied to. When providing your own ScrollController, ensure both the Scrollbar and the Scrollable widget use the same one.

⇒ 잘만들었긴 한데 포지션이 없는데?

⇒ SingleChildWidget을 추가하기

 

  ScrollController chatInputScrollController = ScrollController();
  ...
  

SingleChildScrollView(
                        controller: chatInputScrollController,
                        child: Scrollbar(
                          controller: chatInputScrollController,
...
)

 

 

자, 우리는 이제 디자이너의 모든 요구사항에 맞춘 텍스트필드를 완성했습니다 :)

 

 

전체 코드

Align(
              alignment: Alignment.bottomCenter,
              child: Container(
                //height: 80,
                color: Colors.white,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children: [
                    Container(
                      color: Colors.grey,
                      height: 1,
                    ),
                    Padding(
                      padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
                      child: Container(
                        //height: 48,
                        decoration: BoxDecoration(
                          border: Border.all(color: Colors.grey),
                          borderRadius: BorderRadius.circular(30),
                        ),
                        child: Row(
                          children: [
                            SizedBox(
                              width: SizeConfig().screenWidth - 80,
                              child: SingleChildScrollView(
                                controller: chatInputScrollController,
                                child: ConstrainedBox(
                                  constraints:
                                      const BoxConstraints(maxHeight: 300),
                                  child: Padding(
                                    padding:
                                        EdgeInsets.symmetric(horizontal: 12),
                                    child: TextFormField(
                                      maxLines: 4,
                                      minLines: 1,
                                      onChanged: (value) {},
                                      decoration: InputDecoration(
                                        hintText: '메세지 보내기',
                                        // hintStyle: AppTextStyle.title2R1418
                                        //     .copyWith(color: AppColor.gray500),
                                        border: InputBorder
                                            .none, //const OutlineInputBorder(borderRadius: AppRadius.all8),
                                        //disabledBorder: InputBorder.none,
                                      ),
                                    ),
                                  ),
                                ),
                              ),
                            ),
                            GestureDetector(onTap: () {}, child: Icon(Icons.send))
                          ],
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            )

감사합니다 :)

 

반응형