-
비밀듣는 고양이 앱 제작카테고리 없음 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});
@overrideWidget build(BuildContext context) {return MaterialApp(theme: ThemeData(scaffoldBackgroundColor: Colors.greenAccent, fontFamily: "Neo"),home: MainPage(),);}}
class MainPage extends StatefulWidget {const MainPage({super.key});
@overrideState<MainPage> createState() => _MainPageState();}
class _MainPageState extends State<MainPage> {@overrideWidget 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});
@overrideWidget 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(),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();})),);}}작성자페이지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});
@overrideWidget 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});
@overrideWidget 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데이터에 추가시키는 작업을 수행했다.
작업을 끝내면 스낵바가 나타난다
- Assignment