키보드 높이 만큼 페이지 이동(동적스크롤링)
pages / login_page.dart
CustomTextFormField에 scrollAnimate 함수 넘겨줌
// statefulwidget으로 변경
class LoginPage extends StatefulWidget {
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final _formKey = GlobalKey<FormState>();
//scrollController 생성
late ScrollController scrollController;
@override
void initState() {
// TODO: implement initState
super.initState();
//초기화
scrollController = new ScrollController();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(16.0),
child: ListView(
controller: scrollController,
children: [
SizedBox(height: 100),
Logo("Login"),
SizedBox(height: 50),
buildLoginForm(),
SizedBox(height: 50),
TextButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
Navigator.pushNamed(context, "/home");
}
},
child: Text("Login"),
),
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("New Here? "),
GestureDetector(
onTap: () {
print("Join 클릭");
},
child: Text(
"Join",
style: TextStyle(
fontWeight: FontWeight.bold,
decoration: TextDecoration.underline,
),
),
)
],
),
],
),
),
);
}
Widget buildLoginForm() {
return Form(
key: _formKey,
child: Column(
children: [
CustomTextFormField("Email", scrollAnimate),
CustomTextFormField("Password", scrollAnimate),
],
),
);
}
void scrollAnimate() {
print("탭 클릭됨");
// 6초 후에 실행
Future.delayed(Duration(milliseconds: 600), () {
// MediaQuery.of(context).viewInsets.bottom 하단 inset(사용못하는영역)크기 리턴
// 사용못하는 영역만큼 1초 동안 easeIn으로 이동
scrollController.animateTo(MediaQuery.of(context).viewInsets.bottom,
duration: Duration(milliseconds: 100), curve: Curves.easeIn);
});
}
}
components / custom_text_form_field.dart
import 'package:flutter/material.dart';
class CustomTextFormField extends StatelessWidget {
final String subtitle;
//scrollAnimate 함수 받아오기
final Function scrollAnimate;
const CustomTextFormField(this.subtitle, this.scrollAnimate, {Key? key})
: super(key: key);
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(subtitle),
SizedBox(height: 5),
TextFormField(
onTap: () {
// text field tab할때 실행
scrollAnimate();
},
validator: (value) =>
value!.isEmpty ? "Please Enter some text" : null,
decoration: InputDecoration(
hintText: "Enter $subtitle",
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
),
focusedErrorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
),
),
),
SizedBox(height: 10),
],
);
}
}