Flutter Best Practices

This section will introduce best practices and coding standards in Flutter development.


Code Standards

Naming Conventions

TypeRulesExample
Class nameUpperCamelCaseMyHomePage
Functions/VariableslowerCamelCaseuserName, getData
ConstantsUpper Camel Case + k PrefixkMaxCount
FileLowercase + Underscoremy_home_page.dart

Example: Correct Naming

// Class name - UpperCamelCase
class UserProfilePage extends StatelessWidget {}

// Function - lowerCamelCase
void fetchUserData() {}

// Variable - lowerCamelCase
String userName = 'Zhang San';

// Constants - k prefix
const int kMaxRetryCount = 3;
const String kAppName = 'My App';

// Enum - UpperCamelCase
enum AppState { loading, success, error }

// File name - snake_case
// user_profile_page.dart

Performance Optimization

1. Avoid unnecessary rebuilds

Example: Using const Constructor

// Recommended: use const to reduce rebuilds
const Text('Hello')              // Will not rebuild
const SizedBox(width: 10)

// Avoid: every build creates a new object
Text('Hello')                   // Will rebuild

// Use const in lists
ListView(
  children: const [
    Text('A'),
    Text('B'),
    Text('C'),
  ],
)

2. Use keys to optimize list performance

Example: Using Keys Correctly

// Add unique keys to list items
ListView.builder(
  itemCount: items.length,
  itemBuilder: (context, index) {
    return ListTile(
      key: ValueKey(items[index].id),  // Use unique identifiers as keys
      title: Text(items[index].name),
    );
  },
)

3. Lazy Loading List Items

Example: Using ListView.builder

// Recommended: use builder for lazy loading
ListView.builder(
  itemCount: 1000,  // Must use for large lists
  itemBuilder: (context, index) {
    return ListTile(title: Text('Item $index'));
  },
)

// Avoid: using children to build large lists
ListView(
  children: List.generate(1000, (i) => Text('Item $i')),
)

Project Structure

Example: Recommended Project Structure

// lib/
// ├── main.dart # entry file
// ├── app.dart # app configuration
// ├── core/ # core functionality
// │ ├── constants/ # constants
// │ ├── theme/ # theme
// │ ├── utils/ # utility classes
// │ └── extensions/ # extensions
// ├── data/ # data layer
// │ ├── models/ # data models
// │ ├── repositories/ # Repositories
// │ └── services/ # Network Services
// ├── domain/ # Domain Layer
// │ └── entities/ # Entities
// ├── presentation/ # Presentation Layer
// │ ├── pages/ # Pages
// │ ├── widgets/ # Widgets
// │ └── providers/ # State Management
// └── routes/ # Routes

Error Handling

Example: Global Error Handling

void main() {
  // Global exception capture
  FlutterError.onError = (details) {
    // Log error
    print('Flutter Error: ${details.exception}');
    // Report error to server
    reportError(details.exception);
  };

  // Zone exception capture
  runZonedGuarded(() {
    runApp(const MyApp());
  }, (error, stackTrace) {
    print('Zone Error: $error');
    reportError(error);
  });
}

Following best practices can make code more maintainable, perform better, and reduce bugs in production.

other extensions