Flutter로 반응형 개발자 포트폴리오 웹사이트(앱) 구축
그리고 자신만의 개발자 포트폴리오를 구축해야 한다면 직접 구축하지 않겠습니까!
이 튜토리얼에서는 Flutter로 반응형 개발자 포트폴리오 웹사이트/앱을 구축하는 방법을 단계별로 알려 드리겠습니다. 이 튜토리얼을 따르면 배우게 될 것입니다 -
ScrollController
을 사용하고 프로그래밍 방식으로 스크롤하는 방법. 내용의 테이블
우리가 만들 것
We are going to build a portfolio app with mainly 4 sections about
, skills
, projects
and contact
. For making our app responsive we'll use media query.
라이브 데모
If you are so excited to see what we'll build like me, you can see the live demo of app Here . 이 웹 버전 데모는 html 렌더러를 사용하여 배포됩니다.Live Demo
비디오 설명
At the time of writing this post. It was getting too long so I added this video explanation section.
If you want to watch video tutorial of this post you can watch it from here.
프로젝트 생성
Supposing flutter is installed and initial setup is done in your system.If you have't installed then you can get it from here
VS Code 또는 Android Studio에서 명령 팔레트를 사용하거나 터미널에 다음 명령을 입력하여 새 플러터 프로젝트를 만듭니다.
flutter create <YOUR PROJECT NAME>
초기 설정
Now careate a new folder in your project assets
Inside the assets
folder create a subfolder images
Add an image that you want to show on your portfolio, in your images folder.
Your image should be placed like this
assets/images/
Now load images in pubspec.yaml
file
assets:
- assets/images/
Clear everything from main.dart
file and write the following code.
import 'package:flutter/material.dart';
import 'package:portfolio_app/pages/home_page.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner:false,
home: HomePage(),
);
}
}
디렉토리 설정
Inside the lib
folder create 3 new directory named components
, models
, pages
.
-lib
- components
- models
- pages
홈페이지 만들기
As you can see in the above code we have used HomePage
in the home of MaterialApp
lets create it.
Inside the pages directory create a new file homepage.dart
.
Create a stateless widget HomePage in it like below.
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
//Add Key
appBar: AppBar(
title: const Text(
'JANE DOE',
style: TextStyle(
fontSize: 22,
color: Color(0xFF4756DF),
fontWeight: FontWeight.bold,
),
),
backgroundColor: Colors.white,
elevation: 2,
),
body: SafeArea(
child: Stack(
children: [
SingleChildScrollView(
//Add Scroll Controller
child: Column(
children: const [
],
),
),
],
),
),
);
}
}
Now we need to create a GlobalKey
and a ScrollController
.
GlobalKey - for opening and closing the end drawer that we'll use later.
ScrollController - for scrolling to a specific section of page.
final ScrollController myScrollController = ScrollController();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
add the _scaffoldKey
in the Scaffold widget and myScrollController
in the SingleChildScrollView.
Navbar 섹션 만들기
Because we have to create a responsive UI we'll show the navbar inside the endDrawer
of Scaffold on small screen and inside the actions
of AppBar on large screen.
Inside the components directory caret a new file home_page_actions.dart
and write the following code.
import 'package:flutter/material.dart';
import 'package:portfolio_app/utils.dart';
class HomePageActions extends StatelessWidget {
final ScrollController sc;
const HomePageActions({Key? key, required this.sc}) : super(key: key);
@override
Widget build(BuildContext context) {
bool isMobile = Utils.isMobile(context);
return isMobile
? Column(
children: getWidgets(sc, context, isMobile: true),
)
: Row(
children: getWidgets(sc, context),
);
}
List<Widget> getWidgets(ScrollController sc, BuildContext context,
{bool isMobile = false}) {
int scrollDur = isMobile ? 800 : 500;
return [
Padding(
padding:
EdgeInsets.symmetric(horizontal: 10, vertical: isMobile ? 20 : 0),
child: TextButton(
onPressed: () {
if (isMobile) Navigator.pop(context);
sc.animateTo(
200,
duration: Duration(milliseconds: scrollDur),
curve: Curves.easeIn,
);
},
child: const Text(
'About',
style: TextStyle(
fontSize: 17,
color: Color(0xFf4756DF),
fontWeight: FontWeight.w600,
),
),
),
),
Padding(
padding:
EdgeInsets.symmetric(horizontal: 10, vertical: isMobile ? 20 : 0),
child: TextButton(
onPressed: () {
if (isMobile) Navigator.pop(context);
sc.animateTo(
isMobile ? 1100 : 800,
duration: Duration(milliseconds: scrollDur),
curve: Curves.easeIn,
);
},
child: const Text(
'Skills',
style: TextStyle(
fontSize: 17,
color: Color(0xFf4756DF),
fontWeight: FontWeight.w600,
),
),
),
),
Padding(
padding:
EdgeInsets.symmetric(horizontal: 10, vertical: isMobile ? 20 : 0),
child: TextButton(
onPressed: () {
if (isMobile) Navigator.pop(context);
sc.animateTo(
1400,
duration: Duration(milliseconds: scrollDur),
curve: Curves.easeIn,
);
},
child: const Text(
'Projects',
style: TextStyle(
fontSize: 17,
color: Color(0xFf4756DF),
fontWeight: FontWeight.w600,
),
),
),
),
Padding(
padding:
EdgeInsets.symmetric(horizontal: 10, vertical: isMobile ? 20 : 0),
child: TextButton(
onPressed: () {
if (isMobile) Navigator.pop(context);
sc.animateTo(
isMobile ? 2600 : 1900,
duration: Duration(milliseconds: scrollDur),
curve: Curves.easeIn,
);
},
child: const Text(
'Contact',
style: TextStyle(
fontSize: 17,
color: Color(0xFf4756DF),
fontWeight: FontWeight.w600,
),
),
),
)
];
}
}
There are lots of things in the above code but we'll see only the important one.
As you can see we have used Utils
class so lets create it.
Inside the lib create a new directory called utils.dart
and write the following code.
import 'package:flutter/cupertino.dart';
class Utils {
static bool isMobile(BuildContext context) {
return MediaQuery.of(context).size.width <= 600;
}
static double mdqh(BuildContext context) {
return MediaQuery.of(context).size.height;
}
static double mdqw(BuildContext context) {
return MediaQuery.of(context).size.width;
}
}
the isMobile
method returns true
if the screen width of device is less than or equal to 600 pixel, you can decide your own logic for that.
mdqh
method returns the height of screen
mdqw
method return the width of screen
These utilities will help us to make UI responsive.
Now go to HomePage and inside the AppBar
of Scaffold add the following code.
actions: [
Utils.isMobile(context)
? Padding(
padding: const EdgeInsets.only(right: 10),
child: IconButton(
icon: const Icon(
Icons.menu,
color: Color(0xFf4756DF),
size: 30,
),
onPressed: () {
_scaffoldKey.currentState!.openEndDrawer();
},
),
)
: HomePageActions(
sc: myScrollController,
),
],
and in the Scaffold
of HomePage add the endDrawer
endDrawer: Utils.isMobile(context)
? MyDrawer(
sc: myScrollController,
)
: null,
now lets create our MyDrawer
widget
endDrawer 만들기
Inside the components create a new file my_drawer.dart
and write the following code
import 'package:flutter/material.dart';
import 'package:portfolio_app/components/home_page_actions.dart';
class MyDrawer extends StatelessWidget {
final ScrollController sc;
const MyDrawer({Key? key, required this.sc}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0.0,
leading: IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: const Icon(
Icons.close,
color: Color(0xFF4756DF),
),
),
),
body: Center(child: HomePageActions(sc: sc)),
);
}
}
You can see we are reusing the HomePageActions
again here and it will be visible only on the small screen, remember the code that we wrote in it.
Now inside the HomePage Scaffold
add the floating action button that will help to scroll at top.
floatingActionButton: FloatingActionButton(
mini: Utils.isMobile(context) ? true : false,
onPressed: () {
myScrollController.animateTo(
0,
duration: const Duration(milliseconds: 800),
curve: Curves.easeIn,
);
},
child: Image.network(
'https://eager-williams-af0d00.netlify.app/assets/icons/icons8-upward-arrow.gif',
),
),
animateTo
method of ScrollController will scroll the page to the specified position will nice animation you can define the duration
and curve
for the animation.
The same method we are using in the HomePageActions buttons to scroll at a specific section using a calculated height.
If I write the complete code the article will be too long and boring. So lets quickly complete our project. You can find the source code in the last section
홈페이지 구성요소 생성
Now in the HomePage inside the children
of column add the remaining components.
children: const [
Header1(),
MoreAboutMe(),
SizedBox(height: 50),
TopSkills(),
SizedBox(height: 50),
RecentProjects(),
SizedBox(height: 50),
ContactForm(),
SizedBox(height: 50),
Footer(),
SizedBox(height: 20),
],
이제 HomePage에서 사용한
children
중 Stack
의 맨 아래에 마지막으로 다음 컴포넌트를 추가합니다.const SocialIconsBar(),
프로젝트 모델 생성
In the RecentProjects()
component we need Projectmodel so
in the models directory create a new file called project_model.dart
and write the following code.
lass ProjectModel {
final String imgURL;
final String projectName;
final String? shortDescription;
final String actionLink;
ProjectModel(
{required this.imgURL, required this.projectName, this.shortDescription, required this.actionLink});
}
Create a new file inside the lib called constants.dart
and create some ProjectModels/Demo Projects.
import 'package:portfolio_app/models/project_model.dart';
class Constants {
static final List<ProjectModel> projects = [
ProjectModel(
actionLink: '#',
imgURL:
'https://eager-williams-af0d00.netlify.app/assets/images/expenseTracker.png',
projectName: 'Expense Tracker',
),
ProjectModel(
actionLink: '#',
imgURL:
'https://eager-williams-af0d00.netlify.app/assets/images/netflixClone.png',
projectName: 'Netflix Clone',
),
ProjectModel(
actionLink: '#',
imgURL:
'https://eager-williams-af0d00.netlify.app/assets/images/greenyEarth.png',
projectName: 'Greeny Earth',
),
And we have successfully created our responsive developer portfolio with flutter 🎉
소스 코드
You can see/download the source code from github.Repo Link
감사!
Reference
이 문제에 관하여(Flutter로 반응형 개발자 포트폴리오 웹사이트(앱) 구축), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/pktintali/build-your-own-responsive-developer-portfolio-website-app-with-flutter-k70텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)