مقدمة في Flutter
ما هو Flutter؟
Flutter هو إطار عمل مفتوح المصدر من Google لتطوير تطبيقات الموبايل متعددة المنصات باستخدام لغة Dart.
مميزات Flutter:
- تطوير سريع: Hot Reload للتحديث الفوري للتطبيق
- كود واحد: تطوير تطبيق واحد يعمل على iOS و Android
- أداء عالي: تطبيقات بسرعة تطبيقات native
- UI جميل: واجهات مستخدم عصرية وجذابة
- مجتمع كبير: دعم قوي من Google والمجتمع
مكونات Flutter:
- Flutter SDK: أدوات التطوير الأساسية
- Dart Language: لغة البرمجة المستخدمة
- Flutter Engine: محرك الرندرينغ
- Widgets: مكونات بناء الواجهة
معلومة: Flutter يستخدم Widget-based architecture حيث كل شيء في Flutter هو Widget.
تثبيت Flutter SDK
خطوات التثبيت:
- قم بتحميل Flutter SDK من الموقع الرسمي
- استخرج الملفات في مجلد مناسب
- أضف Flutter إلى PATH
- قم بتشغيل:
flutter doctorللتحقق - ثبت Android Studio أو Xcode حسب المنصة
التحقق من التثبيت:
flutter doctor
يجب أن تظهر جميع العناصر بخضراء ✓ للتأكد من أن كل شيء مثبت بشكل صحيح.
لغة Dart الأساسية
مقدمة عن Dart:
Dart هي لغة برمجة كائنية التوجه طورتها Google، وهي سهلة التعلم ومشابهة للغات مثل Java و JavaScript.
أساسيات Dart:
// المتغيرات
String name = 'أحمد';
int age = 25;
double price = 99.99;
bool isActive = true;
// الدوال
void printName(String name) {
print('الاسم: $name');
}
// Class
class Person {
String name;
int age;
Person(this.name, this.age);
void display() {
print('$name, $age');
}
}
إنشاء أول تطبيق
إنشاء مشروع جديد:
flutter create my_app
cd my_app
flutter run
بنية المشروع:
lib/main.dart: الملف الرئيسيpubspec.yaml: ملف التبعياتandroid/: ملفات Androidios/: ملفات iOS
Widgets الأساسية
ما هي Widgets؟
كل شيء في Flutter هو Widget. Widgets هي مكونات بناء الواجهة.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('أول تطبيق')),
body: Center(child: Text('مرحباً بFlutter!')),
),
);
}
}
StatelessWidget
StatelessWidget:
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text('نص ثابت');
}
}
يستخدم للعناصر التي لا تتغير حالتها.
StatefulWidget
StatefulWidget:
class CounterWidget extends StatefulWidget {
@override
_CounterWidgetState createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
int count = 0;
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('العداد: $count'),
ElevatedButton(
onPressed: () {
setState(() {
count++;
});
},
child: Text('زيادة'),
),
],
);
}
}
Layout Widgets
Widgets التخطيط:
- Row: ترتيب أفقي
- Column: ترتيب عمودي
- Stack: تراكب العناصر
- Container: حاوية قابلة للتخصيص
Row و Column
Row:
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('عنصر 1'),
Text('عنصر 2'),
Text('عنصر 3'),
],
)
Column:
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('عنصر 1'),
Text('عنصر 2'),
],
)
Container و SizedBox
Container:
Container(
width: 200,
height: 100,
color: Colors.blue,
padding: EdgeInsets.all(16),
child: Text('محتوى'),
)
SizedBox:
SizedBox(
width: 100,
height: 50,
child: Text('نص'),
)
Text Widget
Text Widget:
Text(
'مرحباً بFlutter',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Colors.blue,
),
)
Image Widget
عرض الصور:
// من Assets
Image.asset('assets/image.png')
// من Network
Image.network('https://example.com/image.jpg')
// من File
Image.file(File('path/to/image.jpg'))
Button Widgets
أنواع الأزرار:
ElevatedButton(
onPressed: () {},
child: Text('زر مرتفع'),
)
OutlinedButton(
onPressed: () {},
child: Text('زر محدد'),
)
TextButton(
onPressed: () {},
child: Text('زر نصي'),
)
TextField و Input
TextField:
TextField(
decoration: InputDecoration(
labelText: 'الاسم',
hintText: 'أدخل اسمك',
),
onChanged: (value) {
print(value);
},
)
ListView
ListView:
ListView(
children: [
ListTile(title: Text('عنصر 1')),
ListTile(title: Text('عنصر 2')),
ListTile(title: Text('عنصر 3')),
],
)
// ListView.builder
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(title: Text(items[index]));
},
)
GridView
GridView:
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: items.length,
itemBuilder: (context, index) {
return Card(child: Text(items[index]));
},
)
Navigation
التنقل:
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondScreen()),
);
// العودة
Navigator.pop(context);
Routes و Named Routes
Named Routes:
MaterialApp(
routes: {
'/': (context) => HomeScreen(),
'/second': (context) => SecondScreen(),
},
)
// استخدام
Navigator.pushNamed(context, '/second');
State Management الأساسيات
إدارة الحالة:
State Management يساعد في إدارة حالة التطبيق بشكل منظم. من الحلول الشائعة: Provider, Bloc, GetX.
Provider Package
استخدام Provider:
// في pubspec.yaml
dependencies:
provider: ^6.0.0
// Provider
class CounterProvider extends ChangeNotifier {
int count = 0;
void increment() {
count++;
notifyListeners();
}
}
// الاستخدام
Consumer<CounterProvider>(
builder: (context, counter, child) {
return Text('${counter.count}');
},
)
HTTP Requests
طلبات HTTP:
import 'package:http/http.dart' as http;
Future<void> fetchData() async {
var response = await http.get(
Uri.parse('https://api.example.com/data'),
);
print(response.body);
}
JSON Parsing
تحليل JSON:
import 'dart:convert';
var jsonString = '{"name": "أحمد", "age": 25}';
var jsonData = jsonDecode(jsonString);
print(jsonData['name']); // أحمد
Local Storage
SharedPreferences:
import 'package:shared_preferences/shared_preferences.dart';
// حفظ
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString('name', 'أحمد');
// قراءة
String? name = prefs.getString('name');
SQLite Database
SQLite:
import 'package:sqflite/sqflite.dart';
Future<Database> openDatabase() async {
return await openDatabase(
'my_database.db',
version: 1,
onCreate: (db, version) {
db.execute('CREATE TABLE users(id INTEGER PRIMARY KEY, name TEXT)');
},
);
}
Animations
الحركات:
AnimatedContainer(
duration: Duration(seconds: 1),
width: isExpanded ? 200 : 100,
height: isExpanded ? 200 : 100,
color: Colors.blue,
)
Theme و Styling
الثيم:
MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
fontFamily: 'Cairo',
),
)
Forms و Validation
النماذج:
final _formKey = GlobalKey<FormState>();
Form(
key: _formKey,
child: TextFormField(
validator: (value) {
if (value == null || value.isEmpty) {
return 'يرجى إدخال القيمة';
}
return null;
},
),
)
Publishing App
نشر التطبيق:
- قم ببناء APK:
flutter build apk - أو بناء App Bundle:
flutter build appbundle - للـ iOS:
flutter build ios - قم برفع الملف على Google Play أو App Store
Testing
الاختبارات:
// Unit Test
test('should add two numbers', () {
expect(add(2, 3), 5);
});
// Widget Test
testWidgets('should display text', (WidgetTester tester) async {
await tester.pumpWidget(MyWidget());
expect(find.text('Hello'), findsOneWidget);
});
مشروع تطبيقي شامل
تطبيق Todo List:
class TodoApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: TodoListScreen(),
);
}
}
class TodoListScreen extends StatefulWidget {
@override
_TodoListScreenState createState() => _TodoListScreenState();
}
class _TodoListScreenState extends State<TodoListScreen> {
List<String> todos = [];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('قائمة المهام')),
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(title: Text(todos[index]));
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// إضافة مهمة جديدة
},
child: Icon(Icons.add),
),
);
}
}