Flutter

프로필 앱 만들기

whs5758 2025. 8. 18. 21:12

 

theme.dart
import 'package:flutter/material.dart';

const MaterialColor primaryWhite = MaterialColor(
  0xFFFFFFFF,
  <int, Color>{
    50: Color(0xFFFFFFFF),
    100: Color(0xFFFFFFFF),
    200: Color(0xFFFFFFFF),
    300: Color(0xFFFFFFFF),
    400: Color(0xFFFFFFFF),
    500: Color(0xFFFFFFFF),
    600: Color(0xFFFFFFFF),
    700: Color(0xFFFFFFFF),
    800: Color(0xFFFFFFFF),
    900: Color(0xFFFFFFFF),
  },
);

ThemeData mTheme() {
  return ThemeData(
    primarySwatch: primaryWhite,
    appBarTheme: const AppBarTheme(
      iconTheme: IconThemeData(color: Colors.blue),
    ),
  );
}

 

main.dart
import 'package:class_profile/components/profile_buttons.dart';
import 'package:class_profile/components/profile_count_info.dart';
import 'package:class_profile/components/profile_drawer.dart';
import 'package:class_profile/components/profile_header.dart';
import 'package:class_profile/components/profile_tab.dart';
import 'package:class_profile/theme.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: mTheme(),
      debugShowCheckedModeBanner: false,
      home: ProfilePage(),
    );
  }
} // end of class MyApp

class ProfilePage extends StatelessWidget {
  const ProfilePage({super.key});

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        appBar: AppBar(
          leading: Icon(Icons.arrow_back_ios),
          title: Text("Profile"),
          centerTitle: true,
        ),
        endDrawer: ProfileDrawer(),
        body: Column(
          children: [
            const SizedBox(height: 20),
            ProfileHeader(),
            const SizedBox(height: 20),
            ProfileCountInfo(),
            const SizedBox(height: 20),
            ProfileButtons(),
            const SizedBox(height: 20),
            Expanded(child: ProfileTab()),
          ],
        ),
      ),
    );
  }
}

 

profile_drawer.dart
import 'package:flutter/material.dart';

class ProfileDrawer extends StatelessWidget {
  const ProfileDrawer({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 200,
      height: double.infinity,
      color: Colors.blue,
    );
  }
}

 

components/profile_header.dart
import 'package:flutter/material.dart';

class ProfileHeader extends StatelessWidget {
  const ProfileHeader({super.key});

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        const SizedBox(width: 20),
        _buildHeadAvatar(),
        const SizedBox(width: 20),
        _buildHeaderProfile(),
      ],
    );
  }

  Widget _buildHeadAvatar() {
    return SizedBox(
      width: 100,
      height: 100,
      child: CircleAvatar(
        backgroundColor: Colors.amber,
        backgroundImage: AssetImage("assets/avatar.png"),
      ),
    );
  }

  Widget _buildHeaderProfile() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          'LEE',
          style: TextStyle(
            fontSize: 25,
            fontWeight: FontWeight.w700,
          ),
        ),
        Text(
          'Programmer',
          style: TextStyle(
            fontSize: 20,
          ),
        ),
        Text(
          'My Channel',
          style: TextStyle(
            fontSize: 15,
          ),
        ),
      ],
    );
  }
}

 

components/profile_count_info.dart
import 'package:flutter/material.dart';

class ProfileCountInfo extends StatelessWidget {
  const ProfileCountInfo({super.key});

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      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,
    );
  }
}

 

components/profile_buttons.dart
import 'package:flutter/material.dart';

class ProfileButtons extends StatelessWidget {
  const ProfileButtons({super.key});

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceAround,
      children: [
        _buildFollowButton(),
        _buildMessageButton(),
      ],
    );
  }

  Widget _buildFollowButton() {
    return InkWell(
      onTap: () {
        print("Follow Button Click");
      },
      child: Container(
        alignment: Alignment.center,
        // color 속성과 decoration 속성은 동시에 사용 불가
        decoration: BoxDecoration(
          color: Colors.blue,
          borderRadius: BorderRadius.circular(10),
        ),
        width: 150,
        height: 45,
        child: Text(
          "Follow",
          style: TextStyle(color: Colors.white),
        ),
      ),
    );
  }

  Widget _buildMessageButton() {
    return InkWell(
      onTap: () {
        print("Message Button Click");
      },
      child: Container(
        alignment: Alignment.center,
        // color 속성과 decoration 속성은 동시에 사용 불가
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(10),
          border: Border.all(color: Colors.blue),
        ),
        width: 150,
        height: 45,
        child: Text(
          "Message",
          style: TextStyle(color: Colors.blue),
        ),
      ),
    );
  }
}

 

components/profile_tab.dart
import 'package:flutter/material.dart';

class ProfileTab extends StatefulWidget {
  const ProfileTab({super.key});

  @override
  State<ProfileTab> createState() => _ProfileTabState();
} // end of class ProfileTab

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.border_all),
      ),
      Tab(
        icon: Icon(Icons.account_box_rounded),
      ),
    ]);
  }

  Widget _buildTabBarView() {
    return TabBarView(
      children: [
        GridView.builder(
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 3, mainAxisSpacing: 2, crossAxisSpacing: 2),
          itemBuilder: (context, index) {
            return Image.network(
                "https://picsum.photos/id/${index + 1}/200/200");
          },
          itemCount: 50,
        ),
        GridView.builder(
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 3, mainAxisSpacing: 2, crossAxisSpacing: 2),
          itemBuilder: (context, index) {
            return Image.network(
                "https://picsum.photos/id/${index + 50}/200/200");
          },
          itemCount: 50,
        ),
        Container(color: Colors.blue)
      ],
      controller: _tabController,
    );
  }
} // end of private class _ProfileTabState

'Flutter' 카테고리의 다른 글

쇼핑카트 앱 만들기  (0) 2025.08.19
로그인 앱 만들기  (0) 2025.08.19
레시피 앱 만들기  (0) 2025.08.18
스토어 앱 만들기  (1) 2025.08.18
Dart 문법 - final 과 const  (0) 2025.08.18