ABOUT ME

Today
Yesterday
Total
  • 비밀듣는 고양이 앱 제작
    카테고리 없음 2023. 2. 18. 02:53
    • Assignment
      • 제공되는 패키지 secrets_cat_sdk를 활용하여 다음의 기대 결과물을 따라 만드세요.
      • 이번 과제는 최대한 다음의 결과물과 다른 디자인으로 제작하는데 목표를 두세요.
      •  

     

    • Requirements
      • 앱 이름은 [비밀듣는 고양이]가 아닌 다른 이름으로 진행하세요.
      • 앱 내에서 사용될 폰트는 다음과 같습니다.
        • 플러터에 폰트 등록 방법을 검색하여 앱내에 적용할 수 있도록 하세요.
        • neo.ttf
      • 매인 캐릭터 또한 다음의 링크에서 마음에 드는 이미지를 골라서 진행하세요.
      • 페이지들의 배경이미지는 다음의 링크에서 마음에 드는 이미지를 골라서 진행하세요.
      • 각 위젯별 애니메이션은 최소 3개 이상이 적용되어야 합니다. 이 때 적용되는 애니메이션은 자유입니다.
      • 페이지는 3개 이상입니다. 필수 페이지는 다음과 같습니다.
        • SecretPage : 비밀을 볼 수 있는 페이지며, 모든 비밀을 데이터로 불러오며 각 비밀은 페이지로 이루어짐.
        • AuthorPage : 모든 작성자(회원)을 볼 수 있는 페이지
        • UploadPage: 비밀을 업로드할 수 있는 페이지
      • 페키지를 설치하면 Author와 Secret 데이터타입을 사용할 수 있습니다. 데이터와 데이터타입을 활용하여 최대한 위 결과물의 비슷하게 앱을 만들어보세요.

    pubspec.yaml에 이미지랑 폰트를 저장했다

     

    내 메인코드

    import 'package:assigment18/authorpage.dart';
    import 'package:assigment18/secretpage.dart';
    import 'package:assigment18/uploadpage.dart';
    import 'package:flutter/material.dart';
    import 'package:secret_cat_sdk/secret_cat_sdk.dart';
    import 'package:animate_do/animate_do.dart';

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

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

      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          theme: ThemeData(
              scaffoldBackgroundColor: Colors.greenAccent, fontFamily: "Neo"),
          home: MainPage(),
        );
      }
    }

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

      @override
      State<MainPage> createState() => _MainPageState();
    }

    class _MainPageState extends State<MainPage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Container(
            child: Center(
              child: Padding(
                padding: const EdgeInsets.all(24),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    CircleAvatar(
                      radius: 60,
                      backgroundColor: Colors.white60,
                      backgroundImage: NetworkImage(
                    ),
                    SizedBox(
                      height: 8,
                    ),
                    Text(
                      '뉴진스의 하입보이요',
                      style: TextStyle(
                          fontWeight: FontWeight.bold,
                          fontSize: 30,
                          color: Colors.white),
                    ),
                    SizedBox(
                      height: 50,
                    ),
                    ListTile(
                      onTap: () {
                        Navigator.push(context,
                            MaterialPageRoute(builder: ((context) {
                          return SecretPage();
                        })));
                      },
                      tileColor: Colors.white,
                      title: Text('비밀보기'),
                      subtitle: Text('놀러가기'),
                      trailing: Image.network(
                    ),
                    SizedBox(
                      height: 50,
                    ),
                    ListTile(
                      onTap: () {
                        Navigator.push(context,
                            MaterialPageRoute(builder: ((context) {
                          return AuthorPage();
                        })));
                      },
                      tileColor: Colors.white,
                      title: Text('작성자들보기'),
                      subtitle: Text('놀러가기'),
                      trailing: Image.network(
                    ),
                    SizedBox(
                      height: 50,
                    ),
                    ListTile(
                      onTap: () {
                        Navigator.push(context,
                            MaterialPageRoute(builder: ((context) {
                          return UploadPage();
                        })));
                      },
                      tileColor: Colors.white,
                      title: Text('비밀공유'),
                      subtitle: Text('놀러가기'),
                      trailing: Image.network(
                    ),
                  ],
                ),
              ),
            ),
          ),
        );
      }
    }
     ThemeData로 배경색을 greentAccent로 주고 폰트를 설정하고, 각 ListTile을 누르면 해당하는 페이지로 이동할수 있도록 하였다.

    비밀페이지

    import 'package:animate_do/animate_do.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter/src/widgets/container.dart';
    import 'package:flutter/src/widgets/framework.dart';
    import 'package:secret_cat_sdk/secret_cat_sdk.dart';

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

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          extendBodyBehindAppBar: true,
          appBar: AppBar(
            title: Text(
              '뒤로가기',
              style: TextStyle(fontWeight: FontWeight.bold),
            ),
            elevation: 0,
            backgroundColor: Colors.transparent,
          ),
          body: Container(
              alignment: Alignment.center,            //컨테이너 고정
              decoration: BoxDecoration(
                image: DecorationImage(
                    colorFilter: ColorFilter.mode(Colors.black38, BlendMode.darken),  //이미지를 어둡게
                    image: NetworkImage(
                    fit: BoxFit.cover),
              ),
              child: FutureBuilder(
                  future: SecretCatApi.fetchSecrets(),
                  builder: (context, snapshot) {
                    if (snapshot.hasData) {
                      var reversedList = snapshot.data!.reversed.toList();    //★ 리스트를 역순으로 ★
                      return PageView.builder(
                        itemCount: snapshot.data?.length,
                        itemBuilder: (context, index) {
                          return FadeInRight(
                            duration: Duration(seconds: 1),
                            child: Column(
                              crossAxisAlignment: CrossAxisAlignment.center,
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: [
                                CircleAvatar(
                                  radius: 60,
                                  backgroundColor: Colors.white60,
                                  backgroundImage: NetworkImage(
                                      'https://cdn-icons-png.flaticon.com/256/6431/6431327.png'),
                                ),
                                SizedBox(
                                  height: 20,
                                ),
                                Text(
                                  textAlign: TextAlign.center,
                                  reversedList[index].secret,
                                  style: TextStyle(
                                      color: Colors.white,
                                      fontSize: 20,
                                      fontWeight: FontWeight.bold),
                                ),
                                SizedBox(
                                  height: 5,
                                ),
                                Text(
                                  reversedList[index].author?.username ?? "익명",
                                  style: TextStyle(
                                      color: Colors.white,
                                      fontSize: 18,
                                      fontWeight: FontWeight.bold),
                                ),
                              ],
                            ),
                          );
                        },
                      );
                    }
                    return CircularProgressIndicator();
                  })),
        );
      }
    }
     
    옆으로 넘기면 비밀데이터들이 나오게 PageView로 출력하고 animate_do 패키지를 써서 애니메이션효과를 넣엇다.
    작성자페이지
    import 'package:animate_do/animate_do.dart';
    import 'package:flutter/src/widgets/container.dart';
    import 'package:flutter/src/widgets/framework.dart';
    import 'package:flutter/material.dart';
    import 'package:secret_cat_sdk/secret_cat_sdk.dart';

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

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          extendBodyBehindAppBar: true,
          appBar: AppBar(
            title: Text(
              '뒤로가기',
              style: TextStyle(fontWeight: FontWeight.bold),
            ),
            elevation: 0,
            backgroundColor: Colors.transparent,
          ),
          body: Container(
              decoration: BoxDecoration(
                image: DecorationImage(
                    colorFilter: ColorFilter.mode(Colors.black38, BlendMode.darken),
                    image: NetworkImage(
                    fit: BoxFit.cover),
              ),
              child: FutureBuilder(
                  future: SecretCatApi.fetchAuthors(),
                  builder: (context, snapshot) {
                    if (snapshot.connectionState == ConnectionState.done) {
                      return GridView.builder(
                        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                            crossAxisCount: 3),
                        itemCount: snapshot.data!.length,
                        itemBuilder: (context, index) {
                          return ZoomIn(
                            delay: Duration(milliseconds: 300 * index),    //순서대로 0.3초 간격으로 애니메이션(줌인)
                            child: Column(
                              children: [
                                CircleAvatar(
                                    radius: 50,
                                    backgroundColor: Colors.transparent,
                                    backgroundImage: NetworkImage(
                                        snapshot.data![index].avatar!)),
                                SizedBox(
                                  height: 10,
                                ),
                                Text(
                                  textAlign: TextAlign.center,
                                  snapshot.data![index].username,
                                  style: TextStyle(
                                      color: Colors.white,
                                      fontSize: 10,
                                      fontWeight: FontWeight.bold),
                                ),
                              ],
                            ),
                          );
                        },
                      );
                    }
                    return CircularProgressIndicator();
                  })),
        );
      }
    }

     

     
    비밀공유페이지
    import 'package:flutter/material.dart';
    import 'package:flutter/src/widgets/container.dart';
    import 'package:flutter/src/widgets/framework.dart';
    import 'package:secret_cat_sdk/api/api.dart';

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

      @override
      Widget build(BuildContext context) {
        var myController = TextEditingController();
        return Scaffold(
          extendBodyBehindAppBar: true,
          appBar: AppBar(
            title: Text(
              '뒤로가기',
              style: TextStyle(fontWeight: FontWeight.bold),
            ),
            elevation: 0,
            backgroundColor: Colors.transparent,
          ),
          body: Container(
            decoration: BoxDecoration(
              image: DecorationImage(
                  colorFilter: ColorFilter.mode(Colors.black38, BlendMode.darken),
                  image: NetworkImage(
                  fit: BoxFit.cover),
            ),
            child: Padding(
              padding: const EdgeInsets.all(16),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  TextField(
                    decoration:
                        InputDecoration(fillColor: Colors.white30, filled: true,
                                                  focusedBorder: OutlineInputBorder(
                                                  borderSide: BorderSide(color: Colors.pink))
                                                  ),
                    maxLines: 8,
                    controller: myController,
                  ),
                  ElevatedButton(
                      onPressed: () async {
                        if (myController.text != '') {
                          var secret =
                              await SecretCatApi.addSecret(myController.text);
                          if (secret != null) {
                            ScaffoldMessenger.of(context).showSnackBar(
                                SnackBar(content: Text('비밀공유완료~~')));
                          }
                        }
                      },
                      child: Text('비밀공유'))
                ],
              ),
            ),
          ),
        );
      }
    }

    ElevatedButton을 누르면 텍스트필드에 적힌 내용을 secret데이터에 추가시키는 작업을 수행했다.

    작업을 끝내면 스낵바가 나타난다

Designed by Tistory.