מדריך זה מציע מסלול מלא למתחילים ולמתקדמים: מהתקנה, דרך בניית ממשק, ועד חיבור ל-API, ניהול state ו-Flutter Web עם JS.
מה זה Flutter?
Flutter היא מסגרת עבודה של Google לבניית ממשקי משתמש לכל המכשירים: אנדרואיד, iOS, Web ושולחן עבודה. היא משתמשת בשפת Dart ומייצרת ממשק מהיר, מודרני ותגובה גבוהה.
כשהאפליקציה רצה בפלוטר, כל המסך נבנה מרכיבים שנקראים Widgets. כל דבר שנראה על המסך הוא Widget בסופו של דבר.
התקנה ויצירת פרויקט
- הורד והתקן את Flutter SDK מהאתר הרשמי: flutter.dev.
- ודא שיש לך גם Dart ו-Android Studio / Visual Studio Code.
- בחיבור למסוף, הרץ:
flutter doctor
אם הכל בסדר, תראה מסך שמראה את המצב של Flutter, Dart, Android, iOS ו-Web.
יצירת פרויקט חדש
flutter create my_app
cd my_app
לאחר מכן תוכל להריץ:
flutter run
זה יריץ את האפליקציה על אמולטור או מכשיר מחובר.
פקודות שימושיות נוספות ב-Flutter
אלו הפקודות החשובות ביותר שכדאי לדעת כדי לעבוד עם פרויקט Flutter בסיסי.
עדכון תלותות והרצת בדיקות מהירות
flutter pub get
flutter pub upgrade
flutter analyze
flutter pub get מוריד את התלויות שהוגדרו ב-pubspec.yaml.
flutter pub upgrade מעדכן לגרסאות האחרונות שניתן להשתמש בהן.
flutter analyze בודק בעיות סינטקס וקוד בפרויקט.
בניה על פלטפורמות שונות
flutter build apk
flutter build appbundle
flutter build web
flutter build ipa
המחרוזות האלה בונות את האפליקציה ל-Android (APK או App Bundle), ל-Web או ל-iOS.
בדיקה והרצה על מכשירים ואמולטורים
flutter devices
flutter emulators
flutter emulators --launch
flutter devices מראה לך על אילו מכשירים אפשר להריץ.
flutter emulators מנהל את מכשירי האמולציה הזמינים.
לאחר שהמכשיר או האמולטור מחובר, שוב הרץ flutter run.
מבנה פרויקט Flutter
הפרויקט הנוצר כולל את התיקיות והשדות הראשיים:
lib/main.dart- קובץ הכניסה לאפליקציה.pubspec.yaml- הגדרות תלותיות, assets, שם האפליקציה ועוד.android/,ios/,web/- חלקים ספציפיים לכל פלטפורמה.
הקובץ החשוב ביותר בעת לימוד הוא lib/main.dart, שם נגדיר את המבנה הבסיסי של האפליקציה.
דוגמה פשוטה ל-main.dart
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'שלום Flutter',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const HomePage(),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('דף הבית'),
),
body: const Center(
child: Text('שלום עולם בפלוטר!'),
),
);
}
}
Dart - העקרונות הבסיסיים
Dart היא שפת התכנות שמאחורי Flutter. היא קלה להבנה ומבוססת על טיפוסים, פונקציות, מחלקות ומושגים מודרניים.
משתנים וטיפוסים
void main() {
String name = 'Dart';
int age = 10;
double price = 19.99;
bool isReady = true;
print('השם שלי הוא $name');
print('גיל: $age');
print('מחיר: $price');
print('מוכן? $isReady');
}
רשימות ומפות
void main() {
List names = ['אורי', 'נועה', 'תמר'];
Map scores = {
'אורי': 90,
'נועה': 85,
};
print(names[0]);
print(scores['אורי']);
}
לולאות ותנאים
void main() {
for (var i = 1; i <= 5; i++) {
print('מספר $i');
}
int value = 7;
if (value > 5) {
print('גדול מ-5');
} else {
print('לא גדול מ-5');
}
}
פונקציות
String greet(String name) {
return 'שלום $name';
}
void main() {
print(greet('דנה'));
}
מחלקות ו-constructors
class User {
final String name;
final int age;
User({required this.name, required this.age});
}
void main() {
final user = User(name: 'יונתן', age: 25);
print('השם: ${user.name}, גיל: ${user.age}');
}
Widgets בפלוטר
Widgets הם אבן הבניין של כל ממשק Flutter. יש שני סוגים חשובים:
- StatelessWidget - Widget סטטי שאינו משנה את עצמו.
- StatefulWidget - Widget עם מצב פנימי שניתן לעדכן.
StatelessWidget
class HelloWidget extends StatelessWidget {
const HelloWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const Text('שלום!');
}
}
StatefulWidget
class CounterPage extends StatefulWidget {
const CounterPage({Key? key}) : super(key: key);
@override
State createState() => _CounterPageState();
}
class _CounterPageState extends State {
int counter = 0;
void increase() {
setState(() {
counter += 1;
});
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('לחיצות: $counter'),
ElevatedButton(
onPressed: increase,
child: const Text('הגדל'),
),
],
);
}
}
השורה החשובה היא setState(). היא גורמת לפלוטר להריץ את build שוב ולהציג את העדכון.
עיצוב ומבנה מסכים
Flutter מאפשר לבנות פריסות דרך Widgets ייעודיים כמו Row, Column, Container ו-Expanded.
מבנה מסך פשוט
class LayoutExample extends StatelessWidget {
const LayoutExample({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Layout Example')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
padding: const EdgeInsets.all(16),
color: Colors.blue.shade100,
child: const Text('קופסה עם רווחים'),
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Icon(Icons.star, color: Colors.amber),
SizedBox(width: 10),
Text('שורה עם אייקון וטקסט'),
],
),
],
),
),
);
}
}
רשימה גלילה
class ListExample extends StatelessWidget {
const ListExample({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('ListView Example')),
body: ListView(
padding: const EdgeInsets.all(16),
children: List.generate(
10,
(index) => Card(
margin: const EdgeInsets.symmetric(vertical: 8),
child: ListTile(
title: Text('פריט ${index + 1}'),
subtitle: const Text('כותרת משנה'),
),
),
),
),
);
}
}
ניהול State והפעלת קוד
בפלטפורמות מודרניות, מצב (State) הוא מה שמגדיר את השינוי במסך. בפלוטר משתמשים ב-StatefulWidget כדי לנהל מצבים משתנים.
דוגמה לטופס פשוט
class FormPage extends StatefulWidget {
const FormPage({Key? key}) : super(key: key);
@override
State createState() => _FormPageState();
}
class _FormPageState extends State {
final _controller = TextEditingController();
String message = '';
void submit() {
setState(() {
message = 'המשתמש כתב: ${_controller.text}';
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Form Example')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextField(
controller: _controller,
decoration: const InputDecoration(labelText: 'כתבו משהו'),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: submit,
child: const Text('שלח'),
),
const SizedBox(height: 20),
Text(message),
],
),
),
);
}
}
הטיפול בקלט מתבצע דרך TextEditingController ו-setState מעדכן את הטקסט שמוצג על המסך.
קריאת API ו-JSON
כאשר רוצים לקבל נתונים מהאינטרנט, משתמשים ב-HTTP ופורמטי JSON. בדוגמה הזו נתחבר ל-API ונציג את התוצאה.
הוספת תלות ב-http
dependencies:
flutter:
sdk: flutter
http: ^0.13.6
דוגמה לקריאה מ-API
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class ApiPage extends StatefulWidget {
const ApiPage({Key? key}) : super(key: key);
@override
State createState() => _ApiPageState();
}
class _ApiPageState extends State {
String title = 'טוען...';
@override
void initState() {
super.initState();
fetchPost();
}
Future fetchPost() async {
final url = Uri.parse('https://jsonplaceholder.typicode.com/posts/1');
final response = await http.get(url);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
setState(() {
title = data['title'];
});
} else {
setState(() {
title = 'שגיאה בטעינת הנתונים';
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('API Example')),
body: Center(child: Text(title)),
);
}
}
השימוש ב-jsonDecode ממיר מחרוזת JSON למבנה Dart קל לשימוש.
Flutter Web ו-JS
Flutter Web מאפשר להריץ את האפליקציה בדפדפן. אפשר גם לשלב JavaScript ולהשתמש ביכולות דפדפן נוספות.
להלן שתי דרכים נפוצות:
- להטמיע קובץ JavaScript בדף HTML של web.
- להשתמש ב-
dart:jsאוpackage:jsכדי לקרוא ל-JS מתוך Dart.
דוגמה פשוטה ל-JS ב-web/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Flutter Web</title>
<script>
function sayHello(name) {
return 'שלום, ' + name + '!';
}
</script>
</head>
<body>
<script src="main.dart.js"></script>
</body>
</html>
קריאה ל-JS מתוך Dart
import 'dart:js' as js;
void callJs() {
final result = js.context.callMethod('sayHello', ['יוסף']);
print(result); // שלום, יוסף!
}
זה שימושי כאשר רוצים לנצל פונקציות דפדפן ספציפיות או ספריות JS קיימות.
JavaScript להסבר כללי
function greet(name) {
return `שלום ${name}`;
}
console.log(greet('דנה'));
אם אתה מגיע ל-JS בפעם הראשונה, חשוב להבין שזה שפת סקריפט שמשמשת בעיקר בדפדפן וב-Node.js. בפלוטר Web רוב הקוד ב-Dart, אבל ניתן לשלב JS כאשר יש צורך.
Assets וקבצים סטטיים
קבצים סטטיים כמו תמונות, קבצי JSON או פונטים צריכים להירשם ב-pubspec.yaml.
דוגמה לרישום תמונות
flutter:
assets:
- assets/images/logo.png
- assets/data/sample.json
שימוש בתמונה בקוד
Image.asset(
'assets/images/logo.png',
width: 120,
height: 120,
)
נושאים מתקדמים
אדריכלות קוד
כשמסתבכים, הפרד את הקוד לתיקיות:
lib/screens/- מסכים.lib/widgets/- רכיבים קטנים שניתנים לשימוש חוזר.lib/models/- מבני נתונים.lib/services/- חיבור ל-API ולוגיקה עסקית.
State Management
כשאפליקציה גדלה, כדאי להשתמש בפתרונות כמו Provider, Riverpod, Bloc או GetX כדי לנהל מצב במבנים גדולים.
אנימציות בסיסיות
class FadeExample extends StatefulWidget {
const FadeExample({Key? key}) : super(key: key);
@override
State createState() => _FadeExampleState();
}
class _FadeExampleState extends State {
bool visible = true;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('AnimatedOpacity')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AnimatedOpacity(
opacity: visible ? 1 : 0.2,
duration: const Duration(milliseconds: 500),
child: const FlutterLogo(size: 120),
),
const SizedBox(height: 24),
ElevatedButton(
onPressed: () {
setState(() {
visible = !visible;
});
},
child: const Text('החלף מראה'),
),
],
),
),
);
}
}
שימוש ב-Firebase
נושא גדול, אך חשוב לדעת:
- התקן את
firebase_coreואת התוספים המתאימים. - אתחל את Firebase ב-
main(). - השתמש ב-Firestore, Authentication או Storage לפי הצורך.
בעיקרון, גם כאן מדובר בחיבור ל-API חיצוני, וזה נושא דומה לקריאת JSON ו-HttP.
עקרונות להבנת קוד חדש בפלוטר
1. קרא את ה-build()
הפונקציה build() מייצרת את הממשק. היא משתמשת ב-Widgets, ותמיד מחזירה Widget גדול יותר שמכיל את כל המסך.
2. מצא את ה-Widgets הראשיים
חפש Scaffold, AppBar, Column, Row, Text, Image ו-ListView. אלה הרכיבים שמרכיבים את המסך.
3. הפרד קוד לרכיבים
אם מסך ארוך וקשה להבנה, חלק אותו ל-Widgets קטנים עם שמות ברורים. זה הופך כל קוד לקריא יותר.
4. הפשט את הלוגיקה מחוץ ל-UI
שמור חישובים, קריאות API וטיפול בנתונים בקבצים נפרדים ולא בתוך הפונקציה build().
5. נסה לשכתב קוד בהבנה
קרא קטע קוד אחד, נסה להבין מה הוא עושה, ואז כתוב אותו שוב בעצמך. זה תרגיל מעולה שמקבע את ההבנה.
סיכום
במדריך הזה למדנו את היסודות של Flutter ו-Dart, כיצד ליצור מסכים, לנהל מצב, לקרוא API ואת הדרך לשלב JavaScript בפלטפורמת ה-Web.
ברגע שתבין את העיקרון של Widgets ו-build(), תוכל לקחת כל קוד חדש בפלוטר ולהבין אותו, לשנות אותו ולהשתמש בו בפרויקטים שלך.
Flutter בעברית