4주차 주간평가 - rlatkddbs99/Flutter GitHub Wiki
main.dart
import 'package:flutter/material.dart';
import 'package:test1/pages/HomePage.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(), //home페이지 호출
);
}
}
HomePage.dart
import 'package:animated_bottom_navigation_bar/animated_bottom_navigation_bar.dart';
import 'package:flutter/cupertino.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/api/api.dart';
import 'package:test1/pages/authorPage.dart';
import 'package:test1/pages/secretPage.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
var _bottomIndex = 0; //인덱스로 페이지 이동
List pages = [
secretPage(),
authorPage(),
]; //이동할 페이지 리스트
@override
Widget build(BuildContext context) {
var controller = TextEditingController(); //컨트롤러 설정
return Scaffold(
drawer: Drawer(
child: ListView(
children: [
DrawerHeader(child: Text("비밀듣는 고양이 (SNS형)\n스나이퍼 팩토리 교육용앱")),
ListTile(
title: Text("Teddy"),
leading: FaIcon(FontAwesomeIcons.dev),
)
],
),
),
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.transparent,
foregroundColor: Colors.black,
title: Text(
"비밀듣는 고양이",
style: TextStyle(color: Colors.black),
),
),
floatingActionButton: FloatingActionButton(
backgroundColor: Colors.orange,
onPressed: () {
showModalBottomSheet<void>(
isScrollControlled: true, //텍스트 필드 위로 올리기 위함
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
context: context,
builder: (BuildContext context) {
return Container(
padding: EdgeInsets.only(
bottom: MediaQuery.of(context)
.viewInsets
.bottom), //텍스트 필드 위로 올리기 위함
child: Column(
mainAxisSize: MainAxisSize.min, //전체 다 컨테이너가 먹는거 방지
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
"비밀을 공유해볼까요?",
textAlign: TextAlign.center,
),
SizedBox(
height: 4,
),
TextField(
controller: controller,
minLines: 3,
maxLines: 7,
decoration: InputDecoration(
hintText: "비밀을 입력하세요.",
filled: true,
fillColor: Colors.white24),
),
SizedBox(
height: 8,
),
ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.orangeAccent),
onPressed: () async {
if (controller.text != "") {
//텍스트필드 비었을 때 방지
var secret = await SecretCatApi.addSecret(
//텍스트 필드에 있는 텍스트를 비밀에 추가
controller.text);
if (secret != null) {
//비밀을 작성했으면 내려줌
Navigator.pop(context);
}
}
},
child: Text("공유하기"))
],
),
);
});
},
child: Icon(
Icons.add,
color: Colors.white,
)),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
body: pages[_bottomIndex], //페이지 확인, 맞는 페이지 설정
bottomNavigationBar: AnimatedBottomNavigationBar(
icons: [
FontAwesomeIcons.cat,
FontAwesomeIcons.peopleGroup,
],
activeIndex: _bottomIndex, //이동할 페이지
gapLocation: GapLocation.center,
onTap: (index) {
setState(() {
_bottomIndex = index;
});
},
),
);
}
}
secretPage.dart
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:secret_cat_sdk/api/api.dart';
import 'package:intl/intl.dart';
import 'package:test1/SecretCard.dart';
class secretPage extends StatefulWidget {
const secretPage({super.key});
@override
State<secretPage> createState() => _secretPageState();
}
class _secretPageState extends State<secretPage> {
RefreshController _refreshController = RefreshController(); //새로고침
void _onRefresh() async { //새로고침할 때 할거
setState(() {
var result = SecretCatApi.fetchSecrets();
});
_refreshController.loadComplete();
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: SecretCatApi.fetchSecrets(), //뭐할건지, 비밀가져올거야
builder: ((context, snapshot) {
if (snapshot.hasData) { //snapshot에 데이터 있는지
return SmartRefresher(
controller: _refreshController, //컨트롤러 연결
onRefresh: _onRefresh, //함수 연결
enablePullDown: true, //내렸을 때 새로고침
header: WaterDropHeader(), //새로고침 할 때 모습
child: ListView.builder( //어떤 걸 새로고침할지
itemCount: snapshot.data?.length, //표시할 데이터 개수, null이면 계속 생성
itemBuilder: ((context, index) =>
SecretCard(secret: snapshot.data![index]))), //SecretCard호출 하는데 데이터가져가기 거기 필수 속성 secret에 어떤 데이터 들어가는지
);
}
return CircularProgressIndicator(); //로딩
}),
);
}
}
SecretCard.dart
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:intl/intl.dart';
import 'package:secret_cat_sdk/model/secret.dart';
class SecretCard extends StatelessWidget {
const SecretCard({super.key, required this.secret});
final Secret secret;
@override
Widget build(BuildContext context) {
return Container(
//카드 표현
margin: EdgeInsets.all(8),
padding: EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.white12,
borderRadius: BorderRadius.circular(16),
border: Border.all(width: 0.5, color: Colors.grey)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ListTile(
title: Text(
secret.author?.username ??
"익명", //다른 거랑 다르게 secret으로 데이터 접근, secretPage에서 secret으로 데이터 알려줌
),
subtitle: Text(DateFormat("E, MM/dd")
.format(secret.createdAt)), //날짜포멧형식 날자, 몇월/몇일
leading: CircleAvatar(
radius: 24,
backgroundImage: secret.author != null //데이터 접근하기
? NetworkImage(secret.author!.avatar
.toString()) //이미지 글자로 접근, 맞는 아바타 이미지 없으면 null로 표현
: null),
),
Divider(
height: 3,
),
Padding(
padding: const EdgeInsets.all(24),
child: Text(secret.secret),
)
],
),
);
}
}
authorPage.dart
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:secret_cat_sdk/api/api.dart';
class authorPage extends StatefulWidget {
const authorPage({super.key});
@override
State<authorPage> createState() => _authorPageState();
}
class _authorPageState extends State<authorPage> {
RefreshController _refreshController = RefreshController();
void _onRefresh() async {
setState(() {
var res = SecretCatApi.fetchAuthors();
});
_refreshController.refreshCompleted();
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: SecretCatApi.fetchAuthors(), //작성자 가져오기
builder: ((context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
//hasData랑 똑같음
return SmartRefresher(
controller: _refreshController,
enablePullDown: true,
onRefresh: _onRefresh,
header: WaterDropHeader(),
child: ListView.builder(
itemCount: snapshot.data?.length,
itemBuilder: ((context, index) {
return ListTile(
title: Text(snapshot.data![index].username), //데이터 접근
leading: CircleAvatar(
radius: 24,
backgroundImage:
NetworkImage(snapshot.data![index].avatar!),
),
);
}),
),
);
}
return CircularProgressIndicator();
}),
);
}
}