본문 바로가기
IT 정보/플러터 flutter

플러터 Textfield, Textformfield

by 쩜오개미 2023. 10. 16.

Textfield,

 

Center(
  child: Padding(
    child: TextField(
      decoration: InputDecoration(
        labelText: 'Input',
      ),
    ),
    padding: EdgeInsets.all(20.0),
  ),
),

decoration : InputDecoration( 안 쪽

labelStyle: TextStyle(color: Colors.redAccent),
    focusedBorder: OutlineInputBorder(
      borderRadius: BorderRadius.all(Radius.circular(10.0)),
      borderSide: BorderSide(width: 1, color: Colors.redAccent),
    ),
    enabledBorder: OutlineInputBorder(
      borderRadius: BorderRadius.all(Radius.circular(10.0)),
      borderSide: BorderSide(width: 1, color: Colors.redAccent),
    ),
    border: OutlineInputBorder(
      borderRadius: BorderRadius.all(Radius.circular(10.0)),
    ),


decoration 밖

  keyboardType: TextInputType.emailAddress,

 

 

 

 

Overflow 문제 

overflow 발생하는 이유는 text를 입력할때 자판이 위로 올라오면서 자리가 넘쳐서 발생하는 것.

- SingleChildScrollView 로 Column 또는 Container 또는 Padding 또는 TextField 전체를 감싸면 해결

listView나(스크롤할 위젯 많을 때, 보이는 위젯만 렌더링, 더 빠름) 

SingleChildControllView 로 (위젯 적을 때)  사용

이 2가지 모두 scorll이 가능하도록 만들어 줌

 

 

 

 

 

키보드 이외의 영역을 선택하였을 때, 키보드를 사라지게 하기 위해서 

GestureDetector 위젯과 FocusScope 위젯을 사용


아까전에 SingleChildScrollView를 감싸기 


GestureDetector(
  onTap: () => FocusScope.of(context).unfocus(),
  child: SingleChildScrollView(...),
),

 

 

 

입력한 값 밖으로 내보내기

onChanged 

값 입력하면 이 함수가 호출, 여기서 전달되는 값을 setState를 사용하여 저장하면 된다.

 

...
String inputText = '';
...
Text('$inputText')
...
TextField(
onChanged: (text) {
setState(() {
inputText = text;
});
},
...,
)
...

 

 

 

Center(
child: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: SingleChildScrollView(
child: Column(
children: [
Text('$inputText'),
Padding(
padding: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 10.0),
child: TextField(
onChanged: (text) {
setState(() {
inputText = text;
});
},
decoration: InputDecoration(
labelText: 'Email',
hintText: 'Enter your email',
labelStyle: TextStyle(color: Colors.redAccent),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide:
BorderSide(width: 1, color: Colors.redAccent),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide:
BorderSide(width: 1, color: Colors.redAccent),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
),
),
keyboardType: TextInputType.emailAddress,
),
),
],
),
),
),
),

 

TextEditingController

위와 같이 실시간으로 데이터를 갱신할 수도 있지만,

특정 이벤트가 발생하였을 때, 현재 입력된 값에 접근하고 싶을 때

사용하는 것이 TextEditingController이다.

 

 

TextEditingController inputController = TextEditingController();
String inputText = '';
...
Text('$inputText'),
...
TextField(
controller: inputController,
...,
),
...
ElevatedButton(
onPressed: () {
setState(() {
inputText = inputController.text;
});
},
child: Text('Update'),
),
...

 

 

 

class _HomeState extends State<Home> {
  TextEditingController inputController = TextEditingController();
  String inputText = '';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('TextField'),
      ),
      body: Center(
        child: GestureDetector(
          onTap: () => FocusScope.of(context).unfocus(),
          child: SingleChildScrollView(
            child: Column(
              children: [
                Text('$inputText'),
                Padding(
                  padding: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 10.0),
                  child: TextField(
                    controller: inputController,
                    decoration: InputDecoration(
                      labelText: 'Email',
                      hintText: 'Enter your email',
                      labelStyle: TextStyle(color: Colors.redAccent),
                      focusedBorder: OutlineInputBorder(
                        borderRadius: BorderRadius.all(Radius.circular(10.0)),
                        borderSide:
                        BorderSide(width: 1, color: Colors.redAccent),
                      ),
                      enabledBorder: OutlineInputBorder(
                        borderRadius: BorderRadius.all(Radius.circular(10.0)),
                        borderSide:
                        BorderSide(width: 1, color: Colors.redAccent),
                      ),
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.all(Radius.circular(10.0)),
                      ),
                    ),
                    keyboardType: TextInputType.emailAddress,
                  ),
                ),
                ElevatedButton(
                  onPressed: () {
                    setState(() {
                      inputText = inputController.text;
                    });
                  },
                  child: Text('Update'),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

TextEditingController를 먼저 선언한 후, TextField 위젯의 controller 파라메터에 전달해 준다.

그리고 ElevatedButton 버튼이 눌러졌을 때, setState를 사용하여 변수를 업데이트해 준다.

이때, inputController.text와 같이 Textfield 위젯의 입력값에 접근할 수 있다.

이런 방식은 주로 서버에 데이터를 보낼 때 사용된다.

 

 

 

 

중요한 것!!!!

TextEditingController 사용시 반드시 dispose에서 리소스를 해제하자!

클래스 최상위 TextEditingController 선언한 곳 밑,

initState() 선언하는 그곳 아래에 

@override

void dispose() 를 입력한다.

 

@override
void dispose() {
  inputController.dispose();
  super.dispose();
}

 

 

 

 

아까 그  init 위치에 코드를 써서

텍스트필드의 값을 값이 바뀔 때마다 특정행위를 하는 코드 (onchange 안타고 실행)

@override
initState() {
  super.initState();
  
  inputController.addListener(_dolatestValue);
}

@override
void dispose() {
  inputController.dispose();
  super.dispose();
}

_dolatestValue(){
  //값이 바뀔 때마다 할 행위 입력 어디에 값을 넣는다던지 등등
}

 

 

 

 

 

Textformfield

 

TextFormField(
  decoration: InputDecoration(
      border: OutlineInputBorder(),
      contentPadding:
      EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
      hintText: '힌트'
  ),

  validator: (val) {
    if (val!.isEmpty) {
      return "빈칸 입력해주세요";
    }
  },
),

style: TextStyle(color: MangoWhite),

decoration: const InputDecoration( 

labelStyle: TextStyle(color: MangoWhite, fontSize: 15),

),

 

2가지 다 해주면 컬러 바뀜

 

Underline색상 변경

enabledBorder: UnderlineInputBorder()

 

 

 

onSaved(){}.

_formKey.currentState!.save()를 호출해주면 현재 text를 가지고 와서

onSaved()안에 저장해놓았던 모든 내용이 setState()한것처럼 된다

onSaved(String val): { email = val }

 

 

모든 validation을 만족하면 ...

=> if (_formKey.currentState!.validate()) { ... }

TextButton(

  child: Text(

    '로그인',

    style: Theme.of(context) .textTheme .subtitle2! .copyWith(color: Orange700),

    ),

style: TextButton.styleFrom(

    backgroundColor: Theme.of(context).primaryColor,

),

onPressed: () {

    if (_formKey.currentState!.validate()) {

        // 모든 validation을 만족하면 => 어떤 행위를 하도록 코드 작성.

    }

});

 

 

728x90
반응형

댓글