📘 Flutter

[Flutter] TextField 사용하기

핑크빛연어 2021. 7. 7. 10:10

 

안녕하세요! 텍스트를 입력하는 위젯 TextField 에 관해 포스팅해볼게요~

 

안드로이드 에서는 EditText, javaScript 에서는 input 태그 등이 있는데요~

Flutter 에서는 TextField 위젯을 사용해서 사용자가 텍스트를 입력하는 창을 만든다고 하네요 @_@

 

 

 

1. TextFieldPage.dart

 

TextField(...) 위젯의 onSubmitted 호출 시 sendMsg() 메소드를 통해 Toast 를 띄워주도록 하였고,
onChanged 호출 시 checkText() 메소드를 통해 하단 _changedTextWidget 영역에 입력한 텍스트가 바로 보여지도록 구현하였습니다.

TextField(
     controller: _textController,
     onSubmitted: sendMsg,  //키보드로 엔터 클릭 시 호출
     onChanged: checkText,  //text 가 입력될 때 마다 호출
     decoration: InputDecoration(
          // labelText: '텍스트 입력',
          hintText: '텍스트를 입력해주세요',
          border: OutlineInputBorder(), //외곽선
     ),
),

그리고 InputDecoration 의 labelText 와 hintText 가 있는데요,
labelText, hintText 둘 다 초기에는 입력 영역에 해당 글씨를 보여주지만,
labelText 는 TextField 에 포커스가 있을 경우 왼쪽 상단으로 해당 글씨가 보여지는 차이가 있습니다.
아래 화면에서 참고해주세요!

labelText(왼쪽) / hintText(오른쪽)


그리고 SEND 클릭 시 GestureDetector(...) 위젯의 onTap 이 호출되어 sendMsg() 메소드를 통해 Toast 를 띄워주도록 구현하였습니다.

 GestureDetector(
     onTap: () {
           sendMsg(_textController.text);
     },
     child: ...,
)


그리고 Text.rich(...) 위젯과 TextSpan(...) 위젯을 사용하여 다양한 스타일의 텍스트를 한줄에 표시할 수 있습니다.

Text.rich(
     TextSpan(
          text: '=> ', //기본 스타일의 텍스트 (default text style)
          children: [
            TextSpan //TextSpan 위젯을 이용하여 다양한 스타일의 텍스트 사용 가능
              text: '$text',
              style: TextStyle(
                fontSize: 20,
                color: Colors.redAccent,
              ),
            ),
          ],
     ),
),

 

import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';

class TextFieldPage extends StatefulWidget {
  @override
  _TextFieldPageState createState() => _TextFieldPageState();

  const TextFieldPage({Key? key}) : super(key: key);
}

class _TextFieldPageState extends State<TextFieldPage> {
  final TextEditingController _textController = new TextEditingController();
  Widget _changedTextWidget = Container();
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.lightGreen,
        centerTitle: false,
        title: Text(
          'TextFieldPage',
        ),
      ),
      body: Container(
        margin: EdgeInsets.all(30),
        child: _buildTextWidget(),
      ),
    );
  }

  Widget _buildTextWidget() {
    return Container(
      child: Column(
        children: [
          Row(
            children: [
              Flexible(
                child: TextField(
                  controller: _textController,
                  //onSubmitted: sendMsg,
                  //onChanged: checkText,
                  onSubmitted: (text) {
                    sendMsg(text);
                  },
                  onChanged: (text) {
                    checkText(text);
                  },
                  decoration: InputDecoration(
                    // labelText: '텍스트 입력',
                    hintText: '텍스트를 입력해주세요',
                    border: OutlineInputBorder(), //외곽선
                    suffixIcon: _textController.text.isNotEmpty  //엑스버튼
                        ? Container(
                            child: IconButton(
                              alignment: Alignment.centerRight,
                              icon: Icon(
                                Icons.cancel,
                              ),
                              onPressed: () {
                                _textController.clear();
                                setState(() {});
                              },
                            ),
                          )
                        : null,
                  ),
                  ),
                ),
              ),
              GestureDetector(
                onTap: () {
                  sendMsg(_textController.text);
                },
                child: Container(
                  decoration: BoxDecoration(
                    border: Border.all(
                      color: Colors.white,
                    ),
                    borderRadius: BorderRadius.circular(8.0),
                    color: Colors.lightBlue[200],
                  ),
                  margin: const EdgeInsets.symmetric(
                    horizontal: 4.0,
                  ),
                  child: Container(
                    height: 50,
                    width: 50,
                    alignment: Alignment.center,
                    child: Text(
                      'SEND',
                    ),
                  ),
                ),
              ),
            ],
          ),
          Expanded(
            child: Container(
              margin: const EdgeInsets.only(
                top: 30,
                left: 30,
                right: 30,
                bottom: 500,
              ),
              alignment: Alignment.center,
              color: Colors.yellow[200],
              child: _changedTextWidget,
            ),
          ),
        ],
      ),
    );
  }

  void sendMsg(String text) {
    _textController.clear();
    Fluttertoast.showToast(
      msg: text,
      toastLength: Toast.LENGTH_LONG,
      // gravity: ToastGravity.CENTER,  //위치(default 는 아래)
    );
  }

  void checkText(String text) {
    _changedTextWidget = Container(
      child: Text.rich(
        //Text.rich 와 TextSpan 을 사용하여 다양한 스타일의 텍스트를 한줄에 표시할 수 있게 하는 위젯
        TextSpan(
          text: '=> ', //기본 스타일의 텍스트 (default text style)
          children: [
            TextSpan(
              //TextSpan 위젯을 이용하여 다양한 스타일의 텍스트 사용 가능
              text: '$text',
              style: TextStyle(
                fontSize: 20,
                color: Colors.redAccent,
              ),
            ),
          ],
        ),
      ),
    );
    setState(() {}); //setState 를 사용하여 화면 다시 그려줌
  }
}

 

 

 

결과 화면

 

sendMsg() 메소드에서 Toast 띄우는 화면

 

checkText() 메소드에서 Text.rich 와 TextSpan 을 사용한 텍스트 입력 화면

 

감~사~합~니~다~

 

 

더보기

--- TextField 사용 시 문제점 ---

 

TextField 의 onChanged 에서 타이밍 안맞는 문제 : https://zionh.tistory.com/155 에서 참고

TextField 에서 키보드가 화면이 밀려 overflow 생기는 문제 : https://cishome.tistory.com/114 에서 참고

해서 Flutter 사용 시 해결하였습니다. 해당 블로그님들 감사합니당😁

 

728x90
반응형