স্কিপ করে মূল কন্টেন্ট এ যান

Screen Generation Command

flx gen screen কমান্ডটি একটি নতুন স্ক্রিন/পেজ তৈরি করতে ব্যবহৃত হয়। এটি সম্পূর্ণ UI structure, controller, এবং navigation setup সহ একটি কমপ্লিট স্ক্রিন জেনারেট করে।

Basic Usage

flx gen screen screen_name

Advanced Usage

flx gen screen screen_name --type=stateful --controller=getx --with-form

Available Options

OptionDescriptionValuesDefault
--typeScreen typestateless, statefulstateless
--controllerState managementgetx, bloc, nonegetx
--with-formInclude form widgetstrue, falsefalse
--with-navigationInclude navigation setuptrue, falsetrue
--themeUI theme stylematerial, cupertino, custommaterial

Examples

1. Basic Profile Screen

flx gen screen profile

Generated Structure:

lib/features/profile/
├── presentation/
│ ├── pages/
│ │ └── profile_page.dart
│ ├── controllers/
│ │ └── profile_controller.dart
│ └── bindings/
│ └── profile_binding.dart

Generated Code - profile_page.dart:

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../controllers/profile_controller.dart';

class ProfilePage extends GetView<ProfileController> {
const ProfilePage({super.key});


Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Profile'),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: Obx(() {
if (controller.isLoading.value) {
return const Center(
child: CircularProgressIndicator(),
);
}

return SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildHeader(),
const SizedBox(height: 24),
_buildContent(),
],
),
);
}),
);
}

Widget _buildHeader() {
return Container(
width: double.infinity,
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Get.theme.primaryColor,
Get.theme.primaryColor.withOpacity(0.8),
],
),
borderRadius: BorderRadius.circular(12),
),
child: Column(
children: [
CircleAvatar(
radius: 50,
backgroundColor: Colors.white,
child: Icon(
Icons.person,
size: 60,
color: Get.theme.primaryColor,
),
),
const SizedBox(height: 16),
Obx(() => Text(
controller.userName.value,
style: const TextStyle(
color: Colors.white,
fontSize: 24,
fontWeight: FontWeight.bold,
),
)),
],
),
);
}

Widget _buildContent() {
return Column(
children: [
_buildInfoCard('Email', controller.userEmail.value),
_buildInfoCard('Phone', controller.userPhone.value),
_buildInfoCard('Address', controller.userAddress.value),
const SizedBox(height: 24),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: controller.editProfile,
child: const Text('Edit Profile'),
),
),
],
);
}

Widget _buildInfoCard(String label, String value) {
return Card(
margin: const EdgeInsets.only(bottom: 12),
child: ListTile(
title: Text(
label,
style: TextStyle(
fontWeight: FontWeight.w500,
color: Colors.grey[600],
),
),
subtitle: Text(
value,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w400,
),
),
),
);
}
}

Generated Code - profile_controller.dart:

import 'package:get/get.dart';

class ProfileController extends GetxController {
// Observable variables
var isLoading = false.obs;
var userName = 'John Doe'.obs;
var userEmail = 'john.doe@example.com'.obs;
var userPhone = '+1234567890'.obs;
var userAddress = '123 Main St, City, Country'.obs;


void onInit() {
super.onInit();
loadUserProfile();
}

void loadUserProfile() async {
try {
isLoading.value = true;

// Simulate API call
await Future.delayed(const Duration(seconds: 2));

// Load user data
// Replace with actual API call
_updateUserData();

} catch (e) {
Get.snackbar(
'Error',
'Failed to load profile: ${e.toString()}',
snackPosition: SnackPosition.BOTTOM,
);
} finally {
isLoading.value = false;
}
}

void _updateUserData() {
// Update with real data from API
userName.value = 'John Doe';
userEmail.value = 'john.doe@example.com';
userPhone.value = '+1234567890';
userAddress.value = '123 Main St, City, Country';
}

void editProfile() {
Get.toNamed('/edit-profile');
}

void refreshProfile() {
loadUserProfile();
}
}

2. Form-based Settings Screen

flx gen screen settings --with-form --type=stateful

Generated Code - settings_page.dart:

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../controllers/settings_controller.dart';

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


State<SettingsPage> createState() => _SettingsPageState();
}

class _SettingsPageState extends State<SettingsPage> {
final SettingsController controller = Get.put(SettingsController());
final _formKey = GlobalKey<FormState>();


Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Settings'),
actions: [
IconButton(
icon: const Icon(Icons.save),
onPressed: _saveSettings,
),
],
),
body: Obx(() {
if (controller.isLoading.value) {
return const Center(child: CircularProgressIndicator());
}

return Form(
key: _formKey,
child: ListView(
padding: const EdgeInsets.all(16),
children: [
_buildGeneralSection(),
const SizedBox(height: 24),
_buildNotificationSection(),
const SizedBox(height: 24),
_buildPrivacySection(),
const SizedBox(height: 32),
_buildActionButtons(),
],
),
);
}),
);
}

Widget _buildGeneralSection() {
return Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'General Settings',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 16),
TextFormField(
initialValue: controller.username.value,
decoration: const InputDecoration(
labelText: 'Username',
border: OutlineInputBorder(),
),
onChanged: (value) => controller.username.value = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter username';
}
return null;
},
),
const SizedBox(height: 16),
TextFormField(
initialValue: controller.email.value,
decoration: const InputDecoration(
labelText: 'Email',
border: OutlineInputBorder(),
),
onChanged: (value) => controller.email.value = value,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter email';
}
if (!GetUtils.isEmail(value)) {
return 'Please enter valid email';
}
return null;
},
),
],
),
),
);
}

Widget _buildNotificationSection() {
return Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Notifications',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 16),
Obx(() => SwitchListTile(
title: const Text('Push Notifications'),
subtitle: const Text('Receive push notifications'),
value: controller.pushNotifications.value,
onChanged: (value) => controller.pushNotifications.value = value,
)),
Obx(() => SwitchListTile(
title: const Text('Email Notifications'),
subtitle: const Text('Receive email notifications'),
value: controller.emailNotifications.value,
onChanged: (value) => controller.emailNotifications.value = value,
)),
],
),
),
);
}

Widget _buildPrivacySection() {
return Card(
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Privacy & Security',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 16),
Obx(() => SwitchListTile(
title: const Text('Two-Factor Authentication'),
subtitle: const Text('Enable 2FA for extra security'),
value: controller.twoFactorAuth.value,
onChanged: (value) => controller.twoFactorAuth.value = value,
)),
Obx(() => SwitchListTile(
title: const Text('Data Analytics'),
subtitle: const Text('Allow usage data collection'),
value: controller.dataAnalytics.value,
onChanged: (value) => controller.dataAnalytics.value = value,
)),
],
),
),
);
}

Widget _buildActionButtons() {
return Column(
children: [
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: _saveSettings,
child: const Text('Save Settings'),
),
),
const SizedBox(height: 12),
SizedBox(
width: double.infinity,
child: OutlinedButton(
onPressed: _resetSettings,
child: const Text('Reset to Default'),
),
),
],
);
}

void _saveSettings() {
if (_formKey.currentState!.validate()) {
controller.saveSettings();
}
}

void _resetSettings() {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('Reset Settings'),
content: const Text('Are you sure you want to reset all settings to default?'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Cancel'),
),
TextButton(
onPressed: () {
Navigator.pop(context);
controller.resetSettings();
},
child: const Text('Reset'),
),
],
),
);
}
}

3. BLoC-based Dashboard Screen

flx gen screen dashboard --controller=bloc

এটি BLoC pattern ব্যবহার করে dashboard screen জেনারেট করবে।

Screen জেনারেট করার সময় অটোমেটিক navigation route যোগ হয়:

app_routes.dart (GetX):

class AppRoutes {
static const String profile = '/profile';
static const String settings = '/settings';
static const String dashboard = '/dashboard';
}

app_pages.dart (GetX):

class AppPages {
static final routes = [
GetPage(
name: AppRoutes.profile,
page: () => const ProfilePage(),
binding: ProfileBinding(),
),
GetPage(
name: AppRoutes.settings,
page: () => const SettingsPage(),
binding: SettingsBinding(),
),
];
}

Customization Options

Theme Customization

--theme=custom ব্যবহার করে custom theme সহ screen তৈরি করুন:

flx gen screen product --theme=custom

Advanced Options

flx gen screen order_tracking \
--type=stateful \
--controller=bloc \
--with-form \
--with-navigation \
--theme=material

Best Practices

  1. Naming Convention: snake_case ব্যবহার করুন
  2. Screen Organization: প্রতিটি screen-এর জন্য আলাদা feature folder
  3. State Management: প্রোজেক্টের সাথে consistent pattern ব্যবহার করুন
  4. Navigation: Route constants ব্যবহার করুন
  5. Testing: Generated screens-এর জন্য unit tests লিখুন

Troubleshooting

Common Issues

  1. Import Errors: pubspec.yaml-এ সঠিক dependencies আছে কিনা চেক করুন
  2. Route Conflicts: Duplicate route names avoid করুন
  3. Controller Not Found: Binding properly configured আছে কিনা দেখুন

Error Messages

Error: Screen 'home' already exists
Solution: Use --force flag or choose different name
Error: Invalid controller type 'redux'
Solution: Use supported types: getx, bloc, none

এই command আপনার Flutter app development কে অনেক দ্রুত এবং efficient করে তুলবে!