flutter(플러터) - 인스타그램 클론 코딩

JungSik Heo·2026년 4월 29일

flutter

목록 보기
17/23
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Instagram Clone',
      theme: ThemeData.dark(),
      home: LoginScreen(),
    );
  }
}

//////////////////////////////////////////////////////
/// 🔐 로그인 화면
//////////////////////////////////////////////////////
class LoginScreen extends StatelessWidget {
  final TextEditingController emailController = TextEditingController();
  final TextEditingController passwordController = TextEditingController();

  LoginScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 30),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              const Text(
                "Instagram",
                style: TextStyle(
                  fontSize: 40,
                  fontWeight: FontWeight.bold,
                  fontFamily: 'Billabong', // 없어도 동작
                ),
              ),
              const SizedBox(height: 40),

              TextField(
                controller: emailController,
                decoration: InputDecoration(
                  hintText: "Email",
                  filled: true,
                  fillColor: Colors.grey[900],
                  border: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(10),
                  ),
                ),
              ),

              const SizedBox(height: 15),

              TextField(
                controller: passwordController,
                obscureText: true,
                decoration: InputDecoration(
                  hintText: "Password",
                  filled: true,
                  fillColor: Colors.grey[900],
                  border: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(10),
                  ),
                ),
              ),

              const SizedBox(height: 20),

              SizedBox(
                width: double.infinity,
                child: ElevatedButton(
                  onPressed: () {
                    // 로그인 성공 가정
                    Navigator.pushReplacement(
                      context,
                      MaterialPageRoute(
                        builder: (_) => HomeScreen(),
                      ),
                    );
                  },
                  child: const Text("Log in"),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

//////////////////////////////////////////////////////
/// 🏠 홈 피드 화면
//////////////////////////////////////////////////////
class HomeScreen extends StatelessWidget {
  final List<Map<String, String>> posts = [
    {
      "username": "user1",
      "image": "https://picsum.photos/400/400?1"
    },
    {
      "username": "user2",
      "image": "https://picsum.photos/400/400?2"
    },
    {
      "username": "user3",
      "image": "https://picsum.photos/400/400?3"
    },
  ];

  HomeScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Instagram"),
        actions: const [
          Icon(Icons.send),
          SizedBox(width: 10),
        ],
      ),
      body: ListView.builder(
        itemCount: posts.length,
        itemBuilder: (context, index) {
          final post = posts[index];

          return Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              // 사용자 정보
              ListTile(
                leading: const CircleAvatar(
                  backgroundImage:
                      NetworkImage("https://picsum.photos/100"),
                ),
                title: Text(post["username"]!),
                trailing: const Icon(Icons.more_vert),
              ),

              // 이미지
              Image.network(post["image"]!),

              // 액션 버튼
              Row(
                children: [
                  IconButton(
                    icon: const Icon(Icons.favorite_border),
                    onPressed: () {},
                  ),
                  IconButton(
                    icon: const Icon(Icons.comment),
                    onPressed: () {},
                  ),
                  IconButton(
                    icon: const Icon(Icons.send),
                    onPressed: () {},
                  ),
                ],
              ),

              const Padding(
                padding: EdgeInsets.symmetric(horizontal: 12),
                child: Text("좋아요 123개"),
              ),

              const SizedBox(height: 10),
            ],
          );
        },
      ),
    );
  }
}

홈피드

import 'package:flutter/material.dart';

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

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

  
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(useMaterial3: true),
      home: const InstagramHomePage(),
    );
  }
}

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

  
  Widget build(BuildContext context) {
    // 📌 스토리 데이터
    final stories = ["Tom", "Jane", "Mike", "Emma", "Chris", "Lisa"];

    // 📌 피드 데이터
    final feeds = [
      {
        "user": "Tom",
        "profile": "https://i.pravatar.cc/150?img=1",
        "image": "https://picsum.photos/500/500?random=1",
        "likes": "좋아요 120개",
        "caption": "오늘도 즐거운 하루 😄",
      },

      {
        "user": "Jane",
        "profile": "https://i.pravatar.cc/150?img=2",
        "image": "https://picsum.photos/500/500?random=2",
        "likes": "좋아요 300개",
        "caption": "카페에서 커피 ☕",
      },

      {
        "user": "Mike",
        "profile": "https://i.pravatar.cc/150?img=3",
        "image": "https://picsum.photos/500/500?random=3",
        "likes": "좋아요 87개",
        "caption": "여행 중 ✈️",
      },
    ];

    return Scaffold(
      backgroundColor: Colors.white,
      // =====================================================
      // 📌 AppBar
      // =====================================================
      appBar: AppBar(
        backgroundColor: Colors.white,
        elevation: 0,
        title: const Text(
          "Instagram",
          style: TextStyle(
            fontSize: 28,
            fontWeight: FontWeight.bold,
            color: Colors.black,
          ),
        ),

        actions: const [
          Icon(Icons.favorite_border, color: Colors.black),
          SizedBox(width: 20),
          Icon(Icons.send, color: Colors.black),
          SizedBox(width: 15),
        ],
      ),

      // =====================================================
      // 📌 Body
      // =====================================================
      body: ListView(
        children: [
          // =================================================
          // 📌 Story Section
          // =================================================
          SizedBox(
            height: 110,
            child: ListView.builder(
              scrollDirection: Axis.horizontal,
              itemCount: stories.length,
              itemBuilder: (context, index) {
                return Padding(
                  padding: const EdgeInsets.all(10),
                  child: Column(
                    children: [
                      CircleAvatar(
                        radius: 32,
                        backgroundImage: NetworkImage(
                          "https://i.pravatar.cc/150?img=${index + 10}",
                        ),
                      ),
                      const SizedBox(height: 5),
                      Text(stories[index]),
                    ],
                  ),
                );
              },
            ),
          ),

          const Divider(),

          // =================================================
          // 📌 Feed Section
          // =================================================
          ListView.builder(
            shrinkWrap: true,
            physics: const NeverScrollableScrollPhysics(),
            itemCount: feeds.length,

            itemBuilder: (context, index) {
              final feed = feeds[index];

              return Column(
                crossAxisAlignment: CrossAxisAlignment.start,

                children: [
                  // =========================================
                  // 📌 사용자 정보
                  // =========================================
                  ListTile(
                    leading: CircleAvatar(
                      backgroundImage: NetworkImage(feed["profile"]!),
                    ),

                    title: Text(
                      feed["user"]!,
                      style: const TextStyle(fontWeight: FontWeight.bold),
                    ),
                    trailing: const Icon(Icons.more_vert),
                  ),

                  // =========================================
                  // 📌 게시글 이미지
                  // =========================================
                  Image.network(
                    feed["image"]!,
                    width: double.infinity,
                    height: 350,
                    fit: BoxFit.cover,
                  ),

                  // =========================================
                  // 📌 액션 버튼
                  // =========================================
                  const Padding(
                    padding: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
                    child: Row(
                      children: [
                        Icon(Icons.favorite_border, size: 30),
                        SizedBox(width: 15),
                        Icon(Icons.chat_bubble_outline, size: 30),
                        SizedBox(width: 15),
                        Icon(Icons.send, size: 30),
                        Spacer(),
                        Icon(Icons.bookmark_border, size: 30),
                      ],
                    ),
                  ),

                  // =========================================
                  // 📌 좋아요 수
                  // =========================================
                  Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 12),

                    child: Text(
                      feed["likes"]!,

                      style: const TextStyle(fontWeight: FontWeight.bold),
                    ),
                  ),

                  const SizedBox(height: 5),

                  // =========================================
                  // 📌 캡션
                  // =========================================
                  Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 12),

                    child: RichText(
                      text: TextSpan(
                        style: const TextStyle(color: Colors.black),

                        children: [
                          TextSpan(
                            text: "${feed["user"]!} ",

                            style: const TextStyle(fontWeight: FontWeight.bold),
                          ),

                          TextSpan(text: feed["caption"]!),
                        ],
                      ),
                    ),
                  ),

                  const SizedBox(height: 20),
                ],
              );
            },
          ),
        ],
      ),

      // =====================================================
      // 📌 Bottom Navigation
      // =====================================================
      bottomNavigationBar: NavigationBar(
        selectedIndex: 0,

        destinations: const [
          NavigationDestination(icon: Icon(Icons.home), label: "홈"),

          NavigationDestination(icon: Icon(Icons.search), label: "검색"),

          NavigationDestination(
            icon: Icon(Icons.add_box_outlined),
            label: "추가",
          ),

          NavigationDestination(
            icon: Icon(Icons.video_collection_outlined),
            label: "릴스",
          ),

          NavigationDestination(icon: Icon(Icons.person_outline), label: "프로필"),
        ],
      ),
    );
  }
}
profile
쿵스보이(얼짱뮤지션)

0개의 댓글