© Khmer Angkor Academy - sophearithput168

Packages

Flutter Packages

Packages គឺជា reusable libraries ដែលផ្តល់មុខងារជាច្រើនដែលអ្នកអាច integrate ចូលក្នុង Flutter project។ pub.dev គឺជា official package repository មានជាង 40,000+ packages។

� Package Ecosystem Theory

Package Types:

Type Description Example
Dart Packages Pure Dart code (platform-independent) http, provider, intl
Plugin Packages Platform-specific code (iOS/Android) camera, geolocator, battery
Flutter Packages Flutter UI widgets & features flutter_svg, animations

Package Management Workflow:

Package Lifecycle

1️⃣ SEARCH
   - Browse pub.dev
   - Check popularity, likes, pub points
   - Read documentation & examples
   ↓
2️⃣ ADD TO PUBSPEC.YAML
   - Add package name & version
   - Specify dependencies vs dev_dependencies
   ↓
3️⃣ INSTALL
   - Run: flutter pub get
   - Downloads & caches package
   ↓
4️⃣ IMPORT & USE
   - Import in Dart files
   - Use package features
   ↓
5️⃣ UPDATE
   - Check for updates: flutter pub outdated
   - Update: flutter pub upgrade

�📦 Popular Packages (Must-Know)

State Management:

  • provider (6.1.0): Simple & recommended by Flutter team
  • riverpod (2.4.0): Improved provider, compile-safe
  • bloc (8.1.0): Business logic separation pattern
  • get (4.6.0): GetX - all-in-one solution

Networking & Data:

  • http: HTTP requests
  • shared_preferences: Local storage
  • provider: State management
  • image_picker: ជ្រើសរូបភាព
  • sqflite: SQLite database
  • firebase_core: Firebase

➕ ដំឡើង Package

# pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  http: ^1.1.0
  provider: ^6.1.0
flutter pub get

🔍 How to Choose a Good Package

Evaluation Criteria:

Metric Good Warning Signs
Pub Points ✅ 130+ points ❌ < 100 points
Likes ✅ 1000+ likes ❌ < 100 likes
Popularity ✅ 90%+ popularity ❌ < 50%
Last Updated ✅ < 6 months ago ❌ > 1 year ago
Null Safety ✅ Sound null safety ❌ Not null-safe
Documentation ✅ Detailed docs & examples ❌ Poor/no documentation

📝 pubspec.yaml Deep Dive

name: my_app
description: My awesome Flutter app
version: 1.0.0+1

environment:
  sdk: ">=3.0.0 <4.0.0"

# Regular dependencies (included in app)
dependencies:
  flutter:
    sdk: flutter
  
  # Latest compatible version
  http: ^1.1.0
  
  # Specific version
  provider: 6.1.0
  
  # Version range
  shared_preferences: '>=2.0.0 <3.0.0'
  
  # Git repository
  my_package:
    git:
      url: https://github.com/user/my_package.git
      ref: main
  
  # Local path (for development)
  custom_package:
    path: ../custom_package

# Development dependencies (not included in production)
dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^3.0.0
  build_runner: ^2.4.0

# Assets
flutter:
  uses-material-design: true
  assets:
    - images/
    - icons/
  fonts:
    - family: Roboto
      fonts:
        - asset: fonts/Roboto-Regular.ttf

⚙️ Package Commands

# Install packages
flutter pub get

# Update packages to latest compatible versions
flutter pub upgrade

# Update to latest major versions
flutter pub upgrade --major-versions

# Check for outdated packages
flutter pub outdated

# Remove unused packages
flutter pub deps

# Clean cache
flutter pub cache clean

# Repair cache
flutter pub cache repair

🎯 Common Package Examples

1. Using Provider (State Management)

// 1. Add to pubspec.yaml: provider: ^6.1.0

// 2. Create a model
import 'package:flutter/foundation.dart';

class Counter with ChangeNotifier {
  int _count = 0;
  int get count => _count;
  
  void increment() {
    _count++;
    notifyListeners();  // Notify widgets to rebuild
  }
}

// 3. Provide at app level
import 'package:provider/provider.dart';

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => Counter(),
      child: MyApp(),
    ),
  );
}

// 4. Consume in widgets
class CounterWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final counter = Provider.of<Counter>(context);
    
    return Column(
      children: [
        Text('Count: ' + counter.count.toString()),
        ElevatedButton(
          onPressed: counter.increment,
          child: Text('Increment'),
        ),
      ],
    );
  }
}

2. Using Dio (Advanced HTTP)

// 1. Add: dio: ^5.4.0

import 'package:dio/dio.dart';

class ApiService {
  final Dio _dio = Dio(
    BaseOptions(
      baseUrl: 'https://api.example.com',
      connectTimeout: Duration(seconds: 5),
      receiveTimeout: Duration(seconds: 3),
    ),
  );
  
  // Add interceptors (logging, auth, error handling)
  ApiService() {
    _dio.interceptors.add(
      InterceptorsWrapper(
        onRequest: (options, handler) {
          print('REQUEST: ' + options.path);
          // Add auth token
          options.headers['Authorization'] = 'Bearer TOKEN';
          return handler.next(options);
        },
        onResponse: (response, handler) {
          print('RESPONSE: ' + response.statusCode.toString());
          return handler.next(response);
        },
        onError: (error, handler) {
          print('ERROR: ' + error.message.toString());
          return handler.next(error);
        },
      ),
    );
  }
  
  Future<List<dynamic>> getUsers() async {
    try {
      final response = await _dio.get('/users');
      return response.data;
    } on DioException catch (e) {
      if (e.type == DioExceptionType.connectionTimeout) {
        throw Exception('Connection timeout');
      }
      throw Exception('Request failed: ' + e.message.toString());
    }
  }
}

3. Using Cached Network Image

// 1. Add: cached_network_image: ^3.3.0

import 'package:cached_network_image/cached_network_image.dart';

CachedNetworkImage(
  imageUrl: 'https://example.com/image.jpg',
  placeholder: (context, url) => CircularProgressIndicator(),
  errorWidget: (context, url, error) => Icon(Icons.error),
  fadeInDuration: Duration(milliseconds: 500),
  memCacheWidth: 500,  // Resize for memory efficiency
)

4. Using Flutter SVG

// 1. Add: flutter_svg: ^2.0.0

import 'package:flutter_svg/flutter_svg.dart';

// From asset
SvgPicture.asset(
  'assets/logo.svg',
  width: 200,
  height: 200,
  color: Colors.blue,  // Optional color override
)

// From network
SvgPicture.network('https://example.com/icon.svg')

🔧 Creating Your Own Package

# Create a Dart package
flutter create --template=package my_package

# Create a plugin (with platform code)
flutter create --template=plugin --platforms=android,ios my_plugin
// lib/my_package.dart
library my_package;

export 'src/my_feature.dart';

// lib/src/my_feature.dart
class MyFeature {
  String sayHello(String name) {
    return 'Hello, ' + name + '!';
  }
}

💡 Best Practices:

  • ✅ Always check package quality on pub.dev before using
  • ✅ Use caret (^) for version ranges: ^1.2.0 allows 1.2.x and 1.x.x
  • ✅ Run flutter pub outdated regularly
  • ✅ Keep packages updated for security & bug fixes
  • ✅ Use dev_dependencies for tools not needed in production
  • ✅ Read package documentation before using
  • ✅ Check package licenses for commercial projects

⚠️ Common Mistakes:

  • ❌ Using outdated or unmaintained packages
  • ❌ Not specifying version constraints (dangerous)
  • ❌ Adding too many packages (increases app size)
  • ❌ Not checking package compatibility with Flutter version
  • ❌ Ignoring pub points & popularity scores

💡 ជំនួយ: ស្វែងរក packages នៅ pub.dev។ ពិនិត្យ pub points និង popularity មុនប្រើ។ Run flutter pub get បន្ទាប់ពីបន្ថែម package។