카테고리 없음

비밀듣는 고양이 앱 제작

신승호. 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데이터에 추가시키는 작업을 수행했다.

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