사용자의 데이터를 입력받는 폼을 커스텀 해보자
커스텀된 폼필드를 만든다.
CommonFormField(
prefixText: "위치",
hintText: "근처 추천 장소",
),
컴포넌트로 만들어서 필요한 텍스트만 변경할 수 있게 만든다.
Stack
을 이용해서 먼저 입력받을 폼을 만든다.
class CommonFormField extends StatelessWidget {
final prefixText;
final hintText;
const CommonFormField({required this.prefixText, required this.hintText});
Widget build(BuildContext context) {
return Stack(
children: [
TextFormField(
decoration: InputDecoration(
contentPadding: EdgeInsets.only(top: 30, left: 20, bottom: 10),
hintText: hintText,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.black,
width: 2,
),
),
),
),
],
);
}
}
바텀으로 정렬을 하고나서 Positioned
로 Stack위에 다시 텍스트를 쌓는다.
TextFormField(
textAlignVertical: TextAlignVertical.bottom,
// 생략
),
Positioned(
top: 8,
left: 20,
child: Text(
prefixText,
style: TextStyle(
fontSize: 10
), // ???
),
)
SizedBox(
width: double.infinity,
height: 50,
child: TextButton(
style: TextButton.styleFrom(
backgroundColor: Colors.redAccent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
)
,onPressed: (){
print('서브밋 클릭됨');
}, child: Text("검색",
style: TextStyle(
color: Colors.white,
fontSize: 16
),
)),
)
사용자의 디스플레이는 제각각이므로 버튼의 사이즈는 컨테이너가 허용하는 최대범위 안에서 최대한 넓게 잡히는게 좋다.
width: double.infinity
를 이용해서 최대한 늘려준다.
웹이나 모바일은 주로 위아래로 스크롤을 하므로 높이는 고정시키는게 좋다.
어떤 객체를 만들어야 할때 일일이 모든 상태를 입력해서 만든다면 아주 귀찮아질것이다.
이를 편하게 하기 위해서 팩토리 패턴이 존재하는데 TextButton.styleFrom
이 이를 구현하고 있다.
팩토리 메소드 패턴은 객체를 생성하기 위한 인터페이스를 제공하는 패턴으로, 객체의 생성을 서브클래스에게 위임한다.
TextButton
은 ButtonStyle
을 필요로 하는 style
프로퍼티를 가지고 있다.
styleFrom
은 TextButton
의 내부클래스인 ButtonStyle
을 반환하는데 필요한 프로퍼티를 전달해주는 역할을 한다.
하나의 속성만 변경해서 객체를 생성하고 싶다면 styleFrom
대신 of
를 이용한다.
constraints
을 이용해서 컨테이너의 크기 제약조건을 줄수 있다.
Container(
constraints: BoxConstraints(
maxWidth: 250
),
);