Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

온보딩 페이지 추가 #4

Merged
merged 6 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions assets/images/sample.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 2 additions & 8 deletions lib/core/TopScreen.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import 'package:blueberry_flutter_template/feature/post/PostScreen.dart';
import 'package:blueberry_flutter_template/feature/onboarding/OnboardingScreen.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import '../feature/admin/AdminUserListPage.dart';
import '../feature/login/LoginScreen.dart';
import '../feature/map/PoliceMapScreen.dart';
import '../feature/match/MatchScreen.dart';
Expand All @@ -29,7 +28,6 @@ class TopScreen extends ConsumerWidget {
const PoliceMapScreen(),
const MatchScreen(),
const LoginScreen(),
const AdminUserListPage()
];

return Scaffold(
Expand All @@ -54,11 +52,7 @@ class TopScreen extends ConsumerWidget {
BottomNavigationBarItem(
icon: Icon(Icons.account_circle),
label: 'MyPage',
),
BottomNavigationBarItem(
icon: Icon(Icons.admin_panel_settings),
label: 'Admin',
),
)
],
currentIndex: selectedIndex,
onTap: (index) =>
Expand Down
27 changes: 27 additions & 0 deletions lib/feature/onboarding/OnboardingData.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import 'package:blueberry_flutter_template/utils/AppStrings.dart';

import '../../gen/assets.gen.dart';

class OnboardingData {
static const title = "title";
static const description = "description";
static const image = "image";

static final List<Map<String, String>> pageDataList = [
{
title: AppStrings.onboardingTitle,
description: AppStrings.onboardingDescription,
image: Assets.images.sample
},
{
title: AppStrings.onboardingTitle2,
description: AppStrings.onboardingDescription2,
image: Assets.images.sample
},
{
title: AppStrings.onboardingTitle3,
description: AppStrings.onboardingDescription3,
image: Assets.images.sample
},
];
}
79 changes: 79 additions & 0 deletions lib/feature/onboarding/OnboardingScreen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import 'package:blueberry_flutter_template/core/TopScreen.dart';
import 'package:blueberry_flutter_template/feature/onboarding/widgets/OnboardingPageViewBuilder.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

import 'OnboardingData.dart';
import 'widgets/OnboardingDotWidget.dart';
import 'widgets/OnboardingPageButton.dart';

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

@override
_OnboardingScreenState createState() => _OnboardingScreenState();
}

class _OnboardingScreenState extends State<OnboardingScreen> {
late final PageController _pageController;
int _currentPage = 0;

@override
void initState() {
super.initState();
_pageController = PageController();
}

@override
void dispose() {
_pageController.dispose();
super.dispose();
}

void _onPageChanged(int index) {
setState(() {
_currentPage = index;
});
}

void _onNextPressed() {
if (_currentPage == OnboardingData.pageDataList.length - 1) {
context.goNamed(TopScreen.name);
} else {
_pageController.nextPage(
duration: const Duration(milliseconds: 300),
curve: Curves.easeIn,
);
}
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Expanded(
flex: 3,
child: OnboardingPageViewBuilder(
pageController: _pageController,
onPageChanged: _onPageChanged,
),
),
Expanded(
flex: 1,
child: Column(
children: [
OnboardingDotWidget(currentPage: _currentPage),
const SizedBox(height: 20),
OnboardingPageButton(
currentPage: _currentPage,
onNextPressed: _onNextPressed,
),
],
),
),
],
),
);
}
}
33 changes: 33 additions & 0 deletions lib/feature/onboarding/widgets/OnboardingDotWidget.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import 'package:flutter/material.dart';

import '../OnboardingData.dart';

class OnboardingDotWidget extends StatelessWidget {
final int currentPage;

const OnboardingDotWidget({super.key, required this.currentPage});

@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(
OnboardingData.pageDataList.length,
(index) => buildDot(index, currentPage),
),
);
}
}

Widget buildDot(int index, int currentPage) {
return AnimatedContainer(
duration: const Duration(milliseconds: 200),
margin: const EdgeInsets.only(right: 8),
height: 10,
width: currentPage == index ? 20 : 10,
decoration: BoxDecoration(
color: currentPage == index ? Colors.blueAccent : Colors.grey,
borderRadius: BorderRadius.circular(5),
),
);
}
34 changes: 34 additions & 0 deletions lib/feature/onboarding/widgets/OnboardingPageButton.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import 'package:flutter/material.dart';

import '../../../utils/AppStrings.dart';
import '../OnboardingData.dart';

class OnboardingPageButton extends StatelessWidget {
final int currentPage;
final VoidCallback onNextPressed;

const OnboardingPageButton({
super.key,
required this.currentPage,
required this.onNextPressed,
});

@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: onNextPressed,
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
padding: const EdgeInsets.symmetric(horizontal: 50, vertical: 15),
),
child: Text(
currentPage == OnboardingData.pageDataList.length - 1
? AppStrings.onboardingScreenButtonStart
: AppStrings.onboardingScreenButtonNext,
style: const TextStyle(fontSize: 18),
),
);
}
}
42 changes: 42 additions & 0 deletions lib/feature/onboarding/widgets/OnboardingPageItem.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';

class OnboardingPageItem extends StatelessWidget {
final String title;
final String description;
final String image;

const OnboardingPageItem({
super.key,
required this.title,
required this.description,
required this.image,
});

@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SvgPicture.asset(image, height: 300),
const SizedBox(height: 30),
Text(
title,
style: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 15),
Text(
description,
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 16),
),
],
),
);
}
}
30 changes: 30 additions & 0 deletions lib/feature/onboarding/widgets/OnboardingPageViewBuilder.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import 'package:flutter/material.dart';

import '../OnboardingData.dart';
import 'OnboardingPageItem.dart';

class OnboardingPageViewBuilder extends StatelessWidget {
final PageController pageController;
final Function(int) onPageChanged;

const OnboardingPageViewBuilder({
super.key,
required this.pageController,
required this.onPageChanged,
});

@override
Widget build(BuildContext context) {
return PageView.builder(
controller: pageController,
onPageChanged: onPageChanged,
itemCount: OnboardingData.pageDataList.length,
itemBuilder: (context, index) => OnboardingPageItem(
title: OnboardingData.pageDataList[index][OnboardingData.title]!,
description: OnboardingData.pageDataList[index]
[OnboardingData.description]!,
image: OnboardingData.pageDataList[index][OnboardingData.image]!,
),
);
}
}
18 changes: 17 additions & 1 deletion lib/gen/assets.gen.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions lib/utils/AppStrings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,14 @@ class AppStrings {
static const String button_openConfigMenu = '설정 열기';
static const String button_sendMessage = '112 문자보내기';
static const String errorMessage_unknownError = '알 수 없는 오류가 발생했습니다.';

// Onboarding Screen
static const String onboardingTitle = '환영합니다!';
static const String onboardingDescription = '우리 앱으로 최고의 경험을 해보세요.';
static const String onboardingTitle2 = '연결 유지';
static const String onboardingDescription2 = '사랑하는 사람들과 항상 연결되세요.';
static const String onboardingTitle3 = '시작하기';
static const String onboardingDescription3 = '여정을 시작해봅시다!';
static const String onboardingScreenButtonStart = '시작하기';
static const String onboardingScreenButtonNext = '다음';
}
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ flutter:
assets:
- .env
- assets/
- assets/images/
- assets/600x400/
- assets/300x420/
- assets/700x150/
Expand Down
Loading