๐ง Butter & Jam
[Flutter] ์น๋ทฐ ๊ตฌํ(๋ค์ด๋ฒ)
BreadDev
2025. 7. 2. 17:42
728x90
๊ฐ์์์ ๋ฐฐ์ด ๊ธฐ๋ณธ ์ฝ๋๋ฅผ ๊ฐ์ง๊ณ ์ถ๊ฐ๋ก ๊ตฌํํด์ ๋ค์ด๋ฒ ํ๋ฉด์ ์น๋ทฐ๋ฅผ ๊ตฌํํด๋ณด์๋ค.
// ๊ธฐ๋ณธ์ ์ธ StatelessWidget ๊ตฌ์กฐ
class HomeScreen extends StatelessWidget {
WebViewController controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..loadRequest(homeUrl);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(...),
body: WebViewWidget(controller: controller),
);
}
}
1๋จ๊ณ: StatefulWidget์ผ๋ก ๋ณ๊ฒฝ
์ ๋ณ๊ฒฝํ๋?
- ์นํ์ด์ง ๋ก๋ฉ ์ํ ์ถ์ ํ์
- ๋ค๋ก๊ฐ๊ธฐ/์์ผ๋ก๊ฐ๊ธฐ ๋ฒํผ ์ํ ๊ด๋ฆฌ
- ๋์ UI ์ ๋ฐ์ดํธ
ํต์ฌ ๋ณ๊ฒฝ์ฌํญ
class HomeScreen extends StatefulWidget {
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
bool isLoading = true;
bool canGoBack = false;
bool canGoForward = false;
String currentUrl = '';
}
2๋จ๊ณ: ํ์ผ ๊ตฌ์กฐํ
๊ธฐ์กด: ๋จ์ผ ํ์ผ
lib/
โโโ main.dart (๋ชจ๋ ์ฝ๋)
๊ฐ์ : ๊ธฐ๋ฅ๋ณ ๋ถ๋ฆฌ
lib/
โโโ main.dart # ์ฑ ์ง์
์
โโโ constants/app_constants.dart # ์์ ๊ด๋ฆฌ
โโโ screens/home_screen.dart # ๋ฉ์ธ ํ๋ฉด
โโโ widgets/
โโโ loading_widget.dart # ๋ก๋ฉ ์ปดํฌ๋ํธ
โโโ bottom_navigation_widget.dart # ํ๋จ ๋ค๋น๊ฒ์ด์
- ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ ์ฆ๊ฐ
- ์ ์ง๋ณด์ ํธ์์ฑ
- ๊ฐ ํ์ผ์ ์ฑ ์ ๋ช ํํ
3๋จ๊ณ: UI/UX ๊ฐ์
๋ค์ด๋ฒ ์์ ์ ์ฉ
// constants/app_constants.dart
static const Color naverGreen = Color(0xFF03C75A);
๋ก๋ฉ ์ํ ๊ด๋ฆฌ
// NavigationDelegate๋ก ์นํ์ด์ง ์ํ ์ถ์
NavigationDelegate(
onPageStarted: (String url) {
setState(() {
isLoading = true;
currentUrl = url;
});
},
onPageFinished: (String url) async {
setState(() {
isLoading = false;
});
await _updateNavigationState();
},
)
๋ค๋น๊ฒ์ด์ ๋ฒํผ ์ํ ๊ด๋ฆฌ
Future<void> _updateNavigationState() async {
final backStatus = await controller.canGoBack();
final forwardStatus = await controller.canGoForward();
setState(() {
canGoBack = backStatus;
canGoForward = forwardStatus;
});
}
4๋จ๊ณ: ๋ค์ด๋ฒ ์ฑ ๋๋ ์ถ๊ฐ
ํ ํฑ ํผ๋๋ฐฑ
import 'package:flutter/services.dart';
void _refresh() {
controller.reload();
HapticFeedback.lightImpact(); // ํฐ์น ํผ๋๋ฐฑ
}
ํ๋จ ๋ค๋น๊ฒ์ด์ ๋ฐ ๊ตฌํ
// ๋ค์ด๋ฒ ์ฑ๊ณผ ๋์ผํ ๊ตฌ์ฑ
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildBottomNavButton(icon: Icons.home, label: 'ํ'),
_buildBottomNavButton(icon: Icons.search, label: '๊ฒ์'),
_buildBottomNavButton(icon: Icons.newspaper, label: '๋ด์ค'),
_buildBottomNavButton(icon: Icons.shopping_cart, label: '์ผํ'),
],
)
5๋จ๊ณ: ๋ ์ด์์ ์ธ๋ถ ์กฐ์
AppBar ์ ๋ ฌ ๋ณ๊ฒฝ
AppBar(
centerTitle: false, // ๊ธฐ๋ณธ true์์ false๋ก ๋ณ๊ฒฝ
title: Row(
children: [
Icon(Icons.language),
Text('๋ค์ด๋ฒ์น๋ทฐ'), // ํ๊ธ๋ก ๋ณ๊ฒฝ
],
),
)
SafeArea ์ ์ฉ + ์์ ํต์ผ
// ์ฒ์ ์๋ (๋ฌธ์ ๋ฐ์)
SafeArea(child: Container(...)) // ํ๋จ ํฐ์ ์ฌ๋ฐฑ ์๊น
// ์ต์ข
ํด๊ฒฐ
Container(
color: AppConstants.naverGreen, // ์ ์ฒด ์์ญ ์์
child: SafeArea(
child: Container(...), // ์์ ํ ์์ญ์๋ง ์ปจํ
์ธ
),
)
BoxShadow ์ ๊ฑฐ
// ๊ธฐ์กด: decoration ์ฌ์ฉ
decoration: BoxDecoration(
color: AppConstants.naverGreen,
boxShadow: [...], // ์์น ์๋ ์ ์์ฑ
)
// ๊ฐ์ : ๋จ์ color ์ฌ์ฉ
color: AppConstants.naverGreen, // ๊น๋ํ ๋จ์
๊นจ๋ฌ์์
1. ์ํ ๊ด๋ฆฌ์ ์ค์์ฑ
- StatelessWidget → StatefulWidget ๋ณ๊ฒฝ์ผ๋ก ๋์ UI ๊ตฌํ
- setState()๋ฅผ ํตํ ์ค์๊ฐ ์ํ ์ ๋ฐ์ดํธ
2. WebView ์ ์ด
// ๊ธฐ๋ณธ ์ค์
WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setNavigationDelegate(NavigationDelegate(...))
..loadRequest(Uri.parse(url))
// ๋ค๋น๊ฒ์ด์
์ ์ด
await controller.canGoBack()
await controller.goBack()
controller.reload()
3. ์ปดํฌ๋ํธ ๋ถ๋ฆฌ์ ์ฅ์
- ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์์ ฏ ์์ฑ
- ์ฝ๋ ๊ฐ๋ ์ฑ ํฅ์
4. ์ฌ์ฉ์ ๊ฒฝํ ๊ฐ์
- ๋ก๋ฉ ์ํ ํ์
- ํ ํฑ ํผ๋๋ฐฑ
- ์๋ฌ ์ฒ๋ฆฌ ๋ฐ ์ฌ์ฉ์ ์๋ฆผ
5. ๋ ์ด์์ ์ธ๋ถ ์กฐ์
- SafeArea ํ์ฉ๋ฒ
- ์์ ํต์ผ์ฑ ์ ์ง
- AppBar ์ปค์คํฐ๋ง์ด์ง
์ต์ข ๊ฒฐ๊ณผ
์์ฑ๋ ๊ธฐ๋ฅ๋ค:
โ
๋ค์ด๋ฒ ๋ธ๋๋ ์ปฌ๋ฌ ์ ์ฉ
โ
๋ก๋ฉ ์ํ ํ์
โ
๋ค๋น๊ฒ์ด์
๋ฒํผ (๋ค๋ก๊ฐ๊ธฐ, ์์ผ๋ก๊ฐ๊ธฐ, ์๋ก๊ณ ์นจ, ํ)
โ
ํ๋จ ๋ค๋น๊ฒ์ด์
๋ฐ (ํ, ๊ฒ์, ๋ด์ค, ์ผํ)
โ
ํ
ํฑ ํผ๋๋ฐฑ
โ
๋งํฌ ๋ณต์ฌ/๊ณต์ ๊ธฐ๋ฅ
โ
SafeArea ์ ์ฉ
โ
์๋ฌ ์ฒ๋ฆฌ
๐ ํธ๋ฌ๋ธ์ํ ๊ธฐ๋ก
๋ฌธ์ 1: ํ๋จ SafeArea ํฐ์ ์ฌ๋ฐฑ
ํด๊ฒฐ: Container๋ก ์ ์ฒด ์์ญ ์์ ์ง์ ํ SafeArea ์ ์ฉ
๋ฌธ์ 2: BoxShadow๋ก ์ธํ ์์น ์๋ ์
ํด๊ฒฐ: BoxDecoration ์ ๊ฑฐํ๊ณ ๋จ์ color ์์ฑ ์ฌ์ฉ
๋ฌธ์ 3: ์ํ ๊ด๋ฆฌ ๋ถ์กฑ
ํด๊ฒฐ: StatefulWidget ์ ํ + NavigationDelegate ํ์ฉ