[Flutter]채팅 화면 구성

2023. 1. 31. 17:20Flutter

반응형
메세지 관련 설정
//cnt message
int _counter = 0;
//set message controller
final _message = TextEditingController();
//messages
List<String> _messages = [];
메세지 전송 함수
//onPress Button
void _setMessages(){
  setState(() {
    _counter++;
    _messages.add(_message.value.text);
    _message.clear();
  });
  _focusNode.unfocus();
  _focusNode.requestFocus();
}

//onSubmitted [pressed Enter]
void _setMessagesSubmit(String str){
  setState(() {
    _counter++;
    _messages.add(_message.value.text);
    _message.clear();
  });
  _focusNode.unfocus();
  _focusNode.requestFocus();
}
메세지 표시 위젯
Widget _textWidget(int i) {
  return Text(
    _messages[i],
    style: const TextStyle(
      fontSize: 18,
    ),
  );
}
컬럼내부에 스크롤뷰와, textfiled의 비율을 9대1로 설정하여, 메시지 화면 구현
가장 부모 위젯인 SizedBox의 높이를 화면과 동일하게 설정
SizedBox(
  height: MediaQuery.of(context).size.height,
  child: Column(
    children: [
      Expanded(
        flex: 9,
        child: SizedBox(
          child: SingleChildScrollView(
            reverse: true,
            child: SizedBox(
              width: MediaQuery.of(context).size.width,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.start,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  for (int i = 0; i < _counter; i++) _textWidget(i),
                ],
              ),
            ),

          ),
        ),
      ),
      Expanded(
        flex: 1,
        child: TextField(
          controller: _message,
          onSubmitted: _setMessagesSubmit,
          decoration: InputDecoration(
            hintText: "Enter text here",
            suffixIcon: IconButton(
              icon: const Icon(Icons.send),
              onPressed: _setMessages,
            ),
          ),
          focusNode: _focusNode,
        ),
      ),
    ],
  ),
),
전체 코드
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  final _focusNode = FocusNode();

  //cnt message
  int _counter = 0;
  //set message controller
  final _message = TextEditingController();
  //messages
  List<String> _messages = [];

  //onPress Button
  void _setMessages(){
    setState(() {
      _counter++;
      _messages.add(_message.value.text);
      _message.clear();
    });
    _focusNode.unfocus();
    _focusNode.requestFocus();
  }

  //onSubmitted [pressed Enter]
  void _setMessagesSubmit(String str){
    setState(() {
      _counter++;
      _messages.add(_message.value.text);
      _message.clear();
    });
    _focusNode.unfocus();
    _focusNode.requestFocus();
  }

  Widget _textWidget(int i) {
    return Text(
      _messages[i],
      style: const TextStyle(
        fontSize: 18,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: SizedBox(
        height: MediaQuery.of(context).size.height,
        child: Column(
          children: [
            Expanded(
              flex: 9,
              child: SizedBox(
                child: SingleChildScrollView(
                  reverse: true,
                  child: SizedBox(
                    width: MediaQuery.of(context).size.width,
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.start,
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        for (int i = 0; i < _counter; i++) _textWidget(i),
                      ],
                    ),
                  ),

                ),
              ),
            ),
            Expanded(
              flex: 1,
              child: TextField(
                controller: _message,
                onSubmitted: _setMessagesSubmit,
                decoration: InputDecoration(
                  hintText: "Enter text here",
                  suffixIcon: IconButton(
                    icon: const Icon(Icons.send),
                    onPressed: _setMessages,
                  ),
                ),
                focusNode: _focusNode,
              ),
            ),
          ],
        ),
      ),

      // floatingActionButton: FloatingActionButton(
      //   onPressed: _incrementCounter,
      //   tooltip: 'Increment',
      //   child: const Icon(Icons.add),
      // ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}
결과

'Flutter' 카테고리의 다른 글

<Flutter>항목 자동 생성  (0) 2023.01.30
[Flutter]SQLite  (0) 2022.03.07
[Flutter]GetX를 이용한 화면 전환  (0) 2022.02.28
Flutter 세팅 - window  (0) 2022.02.21