사용된 컴포넌트
ThemeData : https://api.flutter.dev/flutter/material/ThemeData-class.html
TabBar : https://api.flutter.dev/flutter/material/TabBar-class.html
TabBarView : https://api.flutter.dev/flutter/material/TabBarView-class.html
AppBar : https://api.flutter.dev/flutter/material/AppBar-class.html
InkWell : https://api.flutter.dev/flutter/material/InkWell-class.html
GridView : https://api.flutter.dev/flutter/widgets/GridView-class.html
Drawer : https://api.flutter.dev/flutter/material/Drawer-class.html
Align : https://api.flutter.dev/flutter/material/Drawer-class.html
Image : https://api.flutter.dev/flutter/dart-ui/Image-class.html
프로젝트 구조
소스코드
pubspec.yaml - 변경후에는 Pub get 버튼을 클릭하여 적용해야 한다.
name: flutter_profile
description: profile Flutter Project
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=2.12.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
fluttertoast: ^8.0.8
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
uses-material-design: true
assets:
- assets/
main.dart
import 'package:flutter/material.dart';
import 'package:flutter_profile/components/profile_buttons.dart';
import 'package:flutter_profile/components/profile_count_info.dart';
import 'package:flutter_profile/components/profile_drawer.dart';
import 'package:flutter_profile/components/profile_header.dart';
import 'package:flutter_profile/components/profile_tab.dart';
import 'package:flutter_profile/theme.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: theme(),
home: ProfilePage(),
);
}
}
class ProfilePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
endDrawer: ProfileDrawer(), //오른쪽에서 왼쪽으로 슬라이드 하는 Drawer
appBar: _buildProfileAppBar(), //앱바
body: Column(
children: [
SizedBox(height: 20,),
ProfileHeader(),
SizedBox(height: 20,),
ProfileCountInfo(),
SizedBox(height: 20,),
ProfileButtons(),
//남아있는 세로 공간을 모두 차지하기 위해 Expanded를 준다.
Expanded(child: ProfileTab()),
],
),
);
}
/// 앱바
AppBar _buildProfileAppBar() {
return AppBar(
leading: Icon(Icons.arrow_back_ios),
title: Text("Profile"),
centerTitle: true,
);
}
}
theme.dart
import 'package:flutter/material.dart';
ThemeData theme() {
return ThemeData(
primaryColor: Colors.white, // 전체적인 색상, default는 blue
accentColor: Colors.blueGrey, // 액센트 색상
appBarTheme: AppBarTheme(
iconTheme: IconThemeData(color: Colors.blue),
),
);
}
profile_buttons.dart
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
class ProfileButtons extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildFollowButton(),
_buildMessageButton(),
],
);
}
// followButton
_buildFollowButton() {
return InkWell(
onTap: () {
print("FollowButton Clicked");
Fluttertoast.showToast(msg: "Follow!", webPosition: "center", webBgColor: "FF0083FF");
},
child: Container(
alignment: Alignment.center,
width: 150,
height: 45,
child: Text(
"Follow",
style: TextStyle(color: Colors.white),
),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(10), // 모서리 둥글게
border: Border.all()
),
),
);
}
_buildMessageButton() {
return InkWell(
onTap: () {
print("MessageButton Clicked");
Fluttertoast.showToast(msg: "Message!", webPosition: "center", webBgColor: "FF0083FF");
},
child: Container(
alignment: Alignment.center,
width: 150,
height: 45,
child: Text(
"Message",
style: TextStyle(color: Colors.black),
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10), // 모서리 둥글게
border: Border.all() // 테두리
),
),
);
}
}
profile_count_info.dart
import 'package:flutter/material.dart';
class ProfileCountInfo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildInfo("50", "Posts"),
_buildLine(),
_buildInfo("10", "Likes"),
_buildLine(),
_buildInfo("3", "Share"),
],
);
}
_buildInfo(String count, String title) {
return Column(
children: [
Text(
count,
style: TextStyle(fontSize: 15),
),
SizedBox(height: 2,),
Text(
title,
style: TextStyle(fontSize: 15),
),
],
);
}
_buildLine() {
return Container(width: 2,height: 60, color: Colors.blue,);
}
}
profile_drawer.dart
import 'package:flutter/material.dart';
/// 넓이가 200인 파란색 Container
class ProfileDrawer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
width: 200,
height: double.infinity, /// 최대 범위로 지정
color: Colors.blue,
);
}
}
profile_header.dart
import 'package:flutter/material.dart';
class ProfileHeader extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
children: [
SizedBox(width: 20,),
_buildHeaderAvator(),
SizedBox(width: 20,),
_buildHeaderProfile(),
],
);
}
Widget _buildHeaderProfile() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start, // 왼쪽 정렬
children: [
Text(
"GetinThere",
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.w700,
),
),
Text(
"프로그래머/작가/강사",
style: TextStyle(
fontSize: 20,
),
),
Text(
"프로그래머",
style: TextStyle(
fontSize: 15,
),
),
],
);
}
_buildHeaderAvator() {
return SizedBox(
width: 100,
height: 100,
child: CircleAvatar( // CircleAvator를 이용하면 둥글게 이미지를 만들 수 있다.
backgroundImage: AssetImage("assets/avator.png"),
),
);
}
}
profile_tab.dart
import 'package:flutter/material.dart';
class ProfileTab extends StatefulWidget {
// 자동으로 생성
const ProfileTab({Key? key}) : super(key: key);
@override
_ProfileTabState createState() => _ProfileTabState();
}
class _ProfileTabState extends State<ProfileTab> with SingleTickerProviderStateMixin {
/**
* 다중 상속을 위해 with 키워드 사용
* SingleTickerProviderStateMixin
* 한개의 애니메이션을 가진 위젯을 정의할 때 사용
* 두개 이상의 애니메이션을 가진 위젯을 경우 TickerProviderStateMixin을 사용.
*/
TabController? _tabController;
@override
void initState() {
/**
* StatefulWidget에만 존재하는 초기화를 위한 함수 (최초 한번만 실행됨)
* vsync: this -> 해당 위젯의 싱크를 SingleTickerProviderStateMixin에 맞춤.
*/
super.initState();
_tabController = new TabController(length: 2, vsync: this);
}
@override
Widget build(BuildContext context) {
return Column(
children: [
_buildTabBar(),
Expanded(child: _buildTabBarView()),
],
);
}
// 탭바를 리턴, controller를 _tabController로 지정
Widget _buildTabBar() {
return TabBar(
controller: _tabController,
tabs: [
Tab(icon: Icon(Icons.directions_car),),
Tab(icon: Icon(Icons.directions_transit))
],
);
}
_buildTabBarView() {
return TabBarView(
controller: _tabController,
children: [
// GridView를 동적으로 생성하기 위해 GridView.builder 사용
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisSpacing: 10,
crossAxisCount: 3,
mainAxisSpacing: 10
),
itemCount: 42,
itemBuilder: (context, index) {
// picsum 사이트에서 제공하는 이미지 가져오기 및 사이즈 지정
return Image.network("https:picsum.photos/id/${index+1}/200/200");
}
),
Container(color: Colors.red,)
],
);
}
}
참조 : https://github.com/flutter-coder/flutter-ui-book1
'개발 > Flutter' 카테고리의 다른 글
[Flutter] 로그인 폼 UI (0) | 2022.01.01 |
---|---|
[Flutter] The flutter tool cannot access the file or directory. (0) | 2021.12.29 |
[Flutter] 플러터로 개발시 유용한 pub.dev (0) | 2021.12.12 |
[Flutter] 레시피 UI 만들기 (1) | 2021.12.12 |
[Fultter] 쇼핑몰 UI 만들기 (0) | 2021.12.03 |
댓글