본문 바로가기
프로그래밍/Flutter

[Flutter] TextFormField 정리

by YuminK 2022. 4. 6.
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

FormKey를 선언하여 사용 영역 widget에 Form을 감싸고 key 속성으로 추가를 해둔다.

이러한 처리를 하는 이유는 나중에 전체 텍스트 필드에 대하여 error가 있는지 판단하기 위함이다.

formKey쪽에서 이를 인식해서 쉽게 이용할 수 있다.

입력할 때 커서 색상, HighLight 색상을 바꾸려면 MaterialApp의 테마에서 해당 속성을 처리하면 된다.

textSelectionTheme: const TextSelectionThemeData(
  cursorColor: Color.fromARGB(255, 255, 0, 255),
  selectionColor: Color.fromARGB(255, 185, 185, 185),
  selectionHandleColor: Color.fromARGB(255, 255, 0, 255),
)

에러가 없는 상태일 때는 항상 회색 박스 처리를 하고 error가 있는 상황에서는 마젠타 색상으로 border를 처리하려고 한다. 미리 OutlineInputBorder를 생성하여 사용한다.

  const accentColor = Color.fromARGB(255, 255, 0, 255);
  const brighterGreyColor = Color.fromARGB(255, 240, 240, 240);
  const greyColor = Color.fromARGB(255, 185, 185, 185);
  
  OutlineInputBorder normalStateBorder = const OutlineInputBorder(
    borderRadius: BorderRadius.all(Radius.circular(4)),
    borderSide: BorderSide(color: Colors.transparent),
  );

  OutlineInputBorder errorStateBorder = const OutlineInputBorder(
  borderRadius: BorderRadius.all(Radius.circular(4)),
  borderSide: BorderSide(color: accentColor));
 
  Widget inputField(BuildContext context, String strField, String strHint, {FormFieldValidator<String>? validator,
      TextInputType inputType = TextInputType.text, bool isPassword = false, int iMaxLength = 30}) {
      return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Padding(
            padding: const EdgeInsets.only(left: margin16, bottom: margin8),
            child: Text(strField,
                style: const TextStyle(
                  color: Colors.black,
                  fontSize: textSize18,
                ))),
 		Padding(
          padding: const EdgeInsets.only(left: 16, right: 16, ), 
          child: SizedBox(
            width: MediaQuery.of(context).size.width,
            height:80, // error 메시지로 인해 높이가 변경되는 것을 막기 위함
            child: TextFormField(
              autovalidateMode: AutovalidateMode.onUserInteraction, // 사용자 입력시 validate처리
              keyboardType: inputType, 
              style: const TextStyle(
                color: Colors.black,
                fontSize: 14,
              ),
              obscureText: isPassword, // 텍스트 숨기기
              maxLength: iMaxLength, // 최대 길이
              decoration: InputDecoration(
                  errorStyle: const TextStyle(height: 0.7 /*내부 영역과 에러 메시지 패딩*/, fontSize: 14, color: accentColor, ),
                  contentPadding: const EdgeInsets.all(16), // 내부 영역 패딩
                  hintText: strHint,
                  hintStyle: const TextStyle(
                      color: greyColor, fontSize: 14),
                  border: normalStateBorder,
                  focusedBorder: normalStateBorder,
                  focusedErrorBorder: errorStateBorder,
                  errorBorder: errorStateBorder,
                  fillColor: brighterGreyColor, // 내부 영역 색상
                  filled: true
              ),
              onSaved: (String? value) {
 
              },
              validator: validator, // (String? text) { return null; or error msg }
            ),
          ),
        ),
      ],
    );
  }

 

SoftKeyboard의 영역 침범 오류를 없애는 방법 중에 하나는 CustomScrollView를 사용하는 것이다. 

slivers 속성에 SliverFillRemaining 처리를 해주고 hasScrollBody 속성을 false로 한다.

이런 식으로 사용하면 위에서 BottomButton을 위해 일부러 영역을 차지하게 둔

Expanded와 같이 사용하는데 문제가 없다.

 CustomScrollView(
      slivers: [
	SliverFillRemaining(
		hasScrollBody: false,
		child: Column(
		  childeren: [
		    TextFormField(initialValue: '아이디',),
		    TextFormField(initialValue: '패스워드',),	
		  ],
		),
	),
  ], 
),

댓글