728x90
반응형
기본 파일 (이미지)
로그인 ui 환경 구현하기
디자인 시안
1. assets 허용하기
assets:
- assets/
2. 폴더 구조
3. Login page
import 'package:flutter/material.dart';
import 'widgets/login_body.dart';
class LoginPage extends StatelessWidget {
const LoginPage({super.key});
@override
Widget build(BuildContext context) {
return LoginBody();
}
}
4. login body
import 'package:class_f_story/_core/constants/size.dart';
import 'package:class_f_story/ui/pages/custom_logo.dart';
import 'package:class_f_story/ui/widgets/custom_auth_text_form_field.dart';
import 'package:class_f_story/ui/widgets/custom_text_button.dart';
import 'package:flutter/material.dart';
import '../../../../widgets/custom_elevated_button.dart';
class LoginBody extends StatelessWidget {
final TextEditingController _usernameController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
LoginBody({super.key});
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: ListView(
padding: EdgeInsets.all(16),
children: [
CustomLogo(title: 'f-story'),
CustomAuthTextFormField(
text: 'Username', textEditingController: _usernameController),
const SizedBox(height: mediumGap),
CustomAuthTextFormField(
text: 'Password',
textEditingController: _passwordController,
obscureText: true,
),
const SizedBox(height: largeGap),
CustomElevatedButton(
text: '로그인',
click: () {
String _uid = _usernameController.text.trim();
String _pass = _passwordController.text.trim();
//TODO : 뷰모델에 있는 기능인 login 행위를 만들어 줄 예정 reapostiroy로 넘겨주기
},
),
CustomTextButton(
text: '회원가입 페이지로 이동',
click: () {
Navigator.pushNamed(context, '/join');
})
],
),
));
}
}
5. custom_logo
import 'package:class_f_story/_core/constants/size.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class CustomLogo extends StatelessWidget {
final String title;
const CustomLogo({required this.title, super.key});
@override
Widget build(BuildContext context) {
return Column(
children: [
const SizedBox(
height: xLargeGap,
),
SvgPicture.asset(
'assets/logo.svg',
width: 70,
height: 70,
),
Text(
'$title',
style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold),
),
const SizedBox(
height: largeGap,
),
],
);
}
}
6. custom_auth_text_form_field
import 'package:class_f_story/_core/constants/size.dart';
import 'package:flutter/material.dart';
class CustomAuthTextFormField extends StatelessWidget {
final String text;
final bool obscureText;
final TextEditingController textEditingController;
const CustomAuthTextFormField(
{required this.text,
required this.textEditingController,
this.obscureText = false,
super.key});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(text),
const SizedBox(height: smallGap),
TextFormField(
controller: textEditingController,
obscureText: obscureText,
decoration: InputDecoration(
hintText: 'Enter $text',
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
borderSide: BorderSide(color: Colors.grey),
),
focusedBorder: OutlineInputBorder(
//손가락 터치시 활성화된 디자인 설정
borderRadius: BorderRadius.circular(20),
),
errorBorder: OutlineInputBorder(
// 유효성 검사실패시 사용되는 디자인 설정
borderRadius: BorderRadius.circular(20),
borderSide: BorderSide(color: Colors.red),
),
focusedErrorBorder: OutlineInputBorder(
//에러가 발생 후 손가락 터치했을때 디자인 설정
borderRadius: BorderRadius.circular(20),
borderSide: BorderSide(color: Colors.red),
),
),
),
],
);
}
}
7. custom_elevated_button
import 'package:class_f_story/_core/constants/size.dart';
import 'package:flutter/material.dart';
class CustomElevatedButton extends StatelessWidget {
final String text;
//final Function(String) click; 동적 으로 받기 위해 생략
final click;
CustomElevatedButton({required this.text, required this.click, super.key});
@override
Widget build(BuildContext context) {
return ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white12,
minimumSize: Size(double.infinity, 50),
foregroundColor: Colors.black,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
)),
onPressed: click,
child: Text('$text'));
}
}
8. custom_text_button
import 'package:flutter/material.dart';
class CustomTextButton extends StatelessWidget {
final String text;
//내장되어있는 빌트인 타입
final VoidCallback click;
const CustomTextButton({required this.text, required this.click, super.key});
@override
Widget build(BuildContext context) {
return TextButton(
onPressed: click,
child: Text(
'$text',
style: TextStyle(
color: Colors.black87, decoration: TextDecoration.underline),
));
}
}
728x90
반응형
'Flutter' 카테고리의 다른 글
[flutter] 블로그 만들기 03 (1) | 2025.02.03 |
---|---|
[flutter] 블로그 만들기01 - 프로젝트 기본설정 (0) | 2025.01.31 |
[flutter] 상태관리되는 ToDo List 만들어보기 (0) | 2025.01.22 |
댓글