8. Flutter 수업- Android Studio로 Profileapp 만들기

Profileapp
홍윤's avatar
Oct 01, 2024
8. Flutter 수업- Android Studio로 Profileapp 만들기

0.파일 구성

💡
notion image

1. ProfileButtons.dart

class ProfileButtons extends StatelessWidget { @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ _buildFollowButton(), _buildMessageButton(), ], ); } Widget _buildFollowButton() { return InkWell( onTap: () { print("Follow 버튼 클릭됨"); }, child: Container( alignment: Alignment.center, //컨테이너 내부 Text 위젯 정렬시 사용 width: 150, height: 45, child: Text( "Follow", style: TextStyle(color: Colors.white), ), decoration: BoxDecoration( color: Colors.blue, borderRadius: BorderRadius.circular(10), ), ), ); } Widget _buildMessageButton() { return InkWell( onTap: () { print("Message 버튼 클릭됨"); }, 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(), //컨테이너에 테두리 선을 준다. ), ), ); } }
notion image
💡

코드설명

팔로우 버튼:
  • _buildFollowButton() 메서드는 팔로우 버튼을 정의하며, InkWell을 사용하여 터치 인터랙션을 추가합니다.
  • 터치 시 "Follow 버튼 클릭됨"이라는 메시지를 출력하며, 버튼은 파란색 배경하얀색 텍스트로 디자인되어 있습니다.
메시지 버튼:
  • _buildMessageButton() 메서드는 메시지 버튼을 정의하며, 이 또한 InkWell터치 인터랙션을 추가합니다.
  • 터치 시 "Message 버튼 클릭됨"이라는 메시지를 출력하며, 버튼은 하얀색 배경검은색 텍스트로 디자인되어 있습니다.
InkWell: 터치 시 시각적 피드백을 제공하며, 버튼 클릭 이벤트를 처리하는 역할을 합니다.
 

2. 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"), ], ); } Widget _buildInfo(String count, String title) { return Column( children: [ Text( count, //변수 바인딩 style: TextStyle(fontSize: 15), ), SizedBox(height: 2), Text( title, //변수 바인딩 style: TextStyle(fontSize: 15), ), ], ); } Widget _buildLine() { return Container( width: 2, height: 60, color: Colors.blue, ); } }
notion image
💡

코드설명

ProfileCountInfo 클래스는 게시물 수, 좋아요 수, 공유 수 등의 정보를 한 줄(Row)로 정렬하는 Flutter 위젯입니다.
buildInfo 메서드:
  • _buildInfo는 두 개의 문자열, 숫자(count)와 제목(title)을 받아 해당 정보를 표시합니다.
  • 두 줄로 구성된 수직 레이아웃을 구현하기 위해 Column을 사용하며, 숫자와 제목은 각각 텍스트 위젯으로 표현됩니다.
buildLine 메서드:
  • _buildLine 메서드는 두 정보 항목 사이에 파란색 구분선을 표시하기 위한 메서드입니다.
  • 구분선은 Container로 정의되며, 2dp의 너비60dp의 높이를 가집니다. 이 선은 각 정보 항목을 구분하는 역할을 합니다.
이 위젯은 게시물 수, 좋아요 수, 공유 수와 같은 프로필 통계 정보를 깔끔하게 한 줄로 배치하는 데 사용됩니다.
 

3. Profile_drawer.dart

import 'package:flutter/material.dart'; class ProfileDrawer extends StatelessWidget { @override Widget build(BuildContext context) { return Container( width: 200, height: double.infinity, color: Colors.blue, ); } }
notion image
notion image
💡

코드설명

  • ProfileDrawer 클래스는 Flutter에서 사이드 메뉴(drawer) 역할을 하는 간단한 위젯입니다.
  • Flutter의 Drawer 기능을 구현하기 위한 기본적인 레이아웃을 구성하고 있습니다. 실제로 Drawer를 만들 때는 Scaffolddrawer 속성에 이 위젯을 전달하여 사이드 메뉴로 사용할 수 있습니다
 

4. Profile_header.dart

import 'package:flutter/material.dart'; class ProfileHeader extends StatelessWidget { @override Widget build(BuildContext context) { return Row( children: [ SizedBox(width: 20), _buildHeaderAvatar(), SizedBox(width: 20), _buildHeaderProfile(), ], ); } Widget _buildHeaderAvatar() { return SizedBox( width: 100, height: 100, child: CircleAvatar( backgroundImage: AssetImage("assets/avatar.png"), )); } 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, ), ), ], ); } }
notion image
💡

코드설명

ProfileHeader 클래스는 프로필 헤더를 구성하는 Flutter 위젯입니다.
  • buildHeaderAvatar 메서드:
    • 이 메서드는 원형 아바타를 생성하는 역할을 합니다.
    • SizedBox로 아바타의 크기를 100x100dp로 설정하고, CircleAvatar 위젯을 사용해 이미지를 원형으로 표시합니다. AssetImage("assets/avatar.png")는 로컬에 저장된 이미지 파일을 불러옵니다.
  • _buildHeaderProfile 메서드:
    • 프로필 정보를 표시하는 부분으로, Column 위젯을 사용하여 정보를 수직으로 나열합니다.
    • 프로필 정보에는 세 가지 텍스트가 포함되며, 각각 이름("GetinThere"), 직업("프로그래머/작가/강사"), 소속("데어 프로그래밍")이 표시됩니다.
    • 텍스트 스타일은 각 텍스트의 크기와 굵기를 달리하여 중요한 정보일수록 크고 굵게 표시합니다:
      • 이름: 25dp, 굵은 글씨
      • 직업: 20dp
      • 소속: 15dp
      • 결론

        이 위젯은 프로필 헤더를 구성하는 데 적합하며, 프로필 사진사용자 정보를 직관적으로 표시합니다. 다양한 앱에서 사용자 프로필을 구성할 때 활용할 수 있는 레이아웃 패턴을 따르고 있으며, 필요에 따라 텍스트와 이미지를 동적으로 교체하여 재사용할 수 있습니다.
 

5. Profile_tab.dart

import 'package:flutter/material.dart'; class ProfileTab extends StatefulWidget { @override _ProfileTabState createState() => _ProfileTabState(); } class _ProfileTabState extends State<ProfileTab> with SingleTickerProviderStateMixin { TabController? _tabController; @override void initState() { super.initState(); _tabController = new TabController(length: 2, vsync: this); } @override Widget build(BuildContext context) { return Column( children: [ _buildTabBar(), Expanded(child: _buildTabBarView()), ], ); } Widget _buildTabBar() { return TabBar( controller: _tabController, tabs: [ Tab(icon: Icon(Icons.directions_car)), Tab(icon: Icon(Icons.directions_transit)), ], ); // end of TabBar } Widget _buildTabBarView() { return TabBarView( controller: _tabController, children: [ GridView.builder( gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisSpacing: 10, crossAxisCount: 3, mainAxisSpacing: 10, ), itemCount: 42, itemBuilder: (context, index) { return Image.network( "https://picsum.photos/id/${index + 1}/200/200"); }, ), Container(color: Colors.red), ], ); } }
notion image
💡

코드설명

ProfileTab 클래스는 탭(Tab)을 통해 두 개의 화면을 전환할 수 있는 구조로 구성된 Flutter 위젯입니다.
  1. StatefulWidget 및 TabController:
      • ProfileTabStatefulWidget으로, 탭 간의 전환을 관리하기 위해 TabController를 사용합니다.
      • SingleTickerProviderStateMixin을 사용하여 애니메이션 효과를 위한 vsync를 제공합니다.
      • TabController는 두 개의 탭을 관리하며, initState()에서 초기화됩니다.
  1. TabBar:
      • _buildTabBar() 메서드는 탭을 표시하는 TabBar를 반환합니다. 두 개의 **아이콘(Tab)**이 탭바에 추가되며, 각각 차 아이콘대중교통 아이콘을 표시합니다.
      • controllerTabController를 연결하여 탭 전환을 제어합니다.
  1. TabBarView:
      • TabBarView는 각 탭에서 표시할 내용을 정의합니다. controller를 통해 탭 전환을 연결합니다.
      • 첫 번째 탭은 **그리드 뷰(GridView)**를 사용하여 이미지를 3개의 열로 배치합니다. 총 42개의 아이템을 표시하며, picsum.photos에서 이미지를 동적으로 불러옵니다.
      • 두 번째 탭은 빨간색 배경의 빈 컨테이너로 구성되어 있습니다.
  1. GridView.builder:
      • GridView.builder는 그리드 형태로 아이템을 동적으로 생성합니다.
      • SliverGridDelegateWithFixedCrossAxisCount을 사용하여 3개의 열로 이미지를 나열하며, 가로 및 세로 간격을 10dp로 설정합니다.
      • itemCount는 42로, 총 42개의 이미지가 그리드로 표시됩니다.
      • itemBuilder는 각각의 이미지 항목을 Image.network()을 통해 URL로 이미지를 불러옵니다.

코드 흐름: 이 코드는 탭을 통한 화면 전환과 그리드 레이아웃을 조합하여 UI를 구성하는 좋은 예시입니다.

 

6. main.dart

import 'package:flutter/material.dart'; import 'package:profileapp1/components/profile_buttons.dart'; import 'package:profileapp1/components/profile_count_info.dart'; import 'package:profileapp1/components/profile_header.dart'; import 'package:profileapp1/components/profile_tab.dart'; import 'package:profileapp1/theme.dart'; import 'components/profile_drawer.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, theme: theme(), home: ProfilePage(), ); } } class ProfilePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( endDrawer: ProfileDrawer(), 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, ); } }
notion image
💡

코드설명

Flutter 프로젝트의 ProfilePage프로필 화면을 구성하는 레이아웃으로, 다양한 컴포넌트를 사용해 하나의 깔끔한 프로필 UI를 제공합니다.

주요 컴포넌트:

  1. ProfileHeader:
      • 프로필 사진과 사용자 정보를 표시하는 프로필 헤더입니다. ProfileHeader는 이미 작성된 클래스(예: 아바타와 텍스트)를 통해 유저 이름과 직업 정보 등을 보여줍니다.
  1. ProfileCountInfo:
      • 게시물 수, 좋아요 수, 공유 수 등 프로필 통계를 나타내는 컴포넌트입니다. 수직으로 배치된 통계 정보와 이를 구분하는 라인이 함께 표시됩니다.
  1. ProfileButtons:
      • 팔로우메시지 버튼을 표시하는 영역입니다. Row 위젯을 사용하여 두 개의 버튼이 나란히 표시됩니다.
  1. ProfileTab:
      • 탭으로 구성된 프로필 상세 정보를 보여주는 컴포넌트입니다. 이 컴포넌트는 그리드 형태로 이미지를 표시하는 첫 번째 탭과, 간단한 컨테이너를 보여주는 두 번째 탭을 포함합니다.
  1. ProfileDrawer:
      • 화면의 오른쪽에서 슬라이드하여 나타나는 사이드바(drawer)입니다. ScaffoldendDrawer 속성으로 적용되며, 사용자가 메뉴를 열 수 있도록 구성되어 있습니다.

ProfilePage 레이아웃:

  • AppBar:
    • 상단 앱바에는 뒤로 가기 버튼과 Profile이라는 타이틀이 표시됩니다. 타이틀은 중앙에 위치하며, 아이콘과 텍스트는 기본적인 앱바 스타일을 따릅니다.
  • Column 레이아웃:
    • Column 위젯을 사용하여 프로필 헤더, 통계, 버튼, 탭을 세로 방향으로 배치합니다. SizedBox를 사용해 각 컴포넌트 사이에 일정한 간격을 추가합니다.
    • 마지막에 ProfileTabExpanded 위젯으로 감싸서 남아 있는 공간을 모두 차지하도록 설정합니다.

최종 구조 설명:

  • 이 레이아웃은 Flutter 앱에서 프로필 화면을 구성하는 매우 효율적인 구조로, 다양한 컴포넌트를 모듈화하여 재사용성을 높였습니다.
  • 다양한 위젯을 조합해 프로필 관련 정보를 한 화면에 표시하면서도, 깔끔하게 각 요소 간의 간격과 정렬을 관리하고 있습니다.
이 전체 레이아웃은 유저 프로필 UI를 구성하는 데 필요한 여러 요소를 포함하며, 확장성을 고려해 컴포넌트가 각각 독립적으로 정의되어 유지보수와 기능 추가가 용이합니다.
Share article

Uni