코딩하는 제리

[Flutter/MiniProject] 간단한 채팅앱 UI 본문

Flutter/MiniProject

[Flutter/MiniProject] 간단한 채팅앱 UI

JerryCho 2021. 3. 17. 23:20

 



소스코드 및 pubspec.yaml

// main.dart

import 'package:flutter/material.dart';
import 'package:minichatapp_jerry/home_page.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.amber,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: HomePage(),
    );
  }
}
// home_page.dart

import 'dart:io';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:minichatapp_jerry/chat_message.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  TextEditingController _textEditingController = TextEditingController();
  GlobalKey<AnimatedListState> _animListKey = GlobalKey<AnimatedListState>();

  List<String> _chats = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: Platform.isIOS
          ? CupertinoNavigationBar(
              middle: Text('Chat App'),
            )
          : AppBar(
              title: Text('Chat App'),
            ),
      body: SafeArea(
        child: Column(
          children: [
            Expanded(
              child: AnimatedList(
                key: _animListKey,
                reverse: true /*리스트뷰를 뒤집음*/,
                itemBuilder: _buildItem,
              ),
            ),
            Container(
              padding: EdgeInsets.symmetric(horizontal: 8),
              child: Row(
                children: [
                  Expanded(
                    child: Platform.isIOS
                        ? CupertinoTextField(
                            controller: _textEditingController,
                            placeholder: '메시지 입력',
                            onSubmitted: _handleSubmitted /*키보드 엔터 버튼으로 보내기*/,
                          )
                        : TextField(
                            controller: _textEditingController,
                            decoration: InputDecoration(hintText: '메시지 입력'),
                            onSubmitted: _handleSubmitted /*키보드 엔터 버튼으로 보내기*/,
                          ),
                  ),
                  SizedBox(width: 8.0),
                  Platform.isIOS
                      ? CupertinoButton(
                          child: Text('send'),
                          onPressed: () {
                            _handleSubmitted(_textEditingController.text);
                          })
                      : IconButton(
                          onPressed: () {
                            _handleSubmitted(_textEditingController.text);
                          },
                          icon: Icon(Icons.send),
                          color: Colors.amberAccent,
                        ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildItem(context, index, animation) {
    return ChatMessage(_chats[index], animation: animation);
  }

  void _handleSubmitted(String text) {
    print(text);
    _textEditingController.clear();
    // 리스트의 첫번째에 저장
    _chats.insert(0, text);
    _animListKey.currentState.insertItem(0);
  }
}
// chat_message.dart

import 'package:flutter/material.dart';

class ChatMessage extends StatelessWidget {
  final String text;
  final Animation<double> animation;

  const ChatMessage(this.text, {Key key, @required this.animation})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
      child: FadeTransition(
        opacity: animation,
        child: SizeTransition(
          sizeFactor: animation,
          axisAlignment: -1.0 /* -1.0 : 상단부터 생성, 1.0 : 하단부터 생성 */,
          child: Row(
            children: [
              CircleAvatar(
                backgroundColor: Colors.amberAccent,
                child: Text('test'),
              ),
              SizedBox(
                width: 16,
              ),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text(
                      'ID or Name',
                      style: TextStyle(fontWeight: FontWeight.bold),
                    ),
                    Text(text),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
Comments