← Назад к вопросам

Приведи пример использования SharedPreferences

1.0 Junior🔥 161 комментариев
#Хранение данных

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Пример использования SharedPreferences

SharedPreferences — это самый простой способ сохранять небольшие объемы данных локально на устройстве. Это key-value хранилище, которое сохраняется между запусками приложения.

Что такое SharedPreferences?

SharedPreferences позволяет:

  • Сохранять простые типы данных (String, int, bool, double, List<String>)
  • Быстро читать данные
  • Персистировать состояние приложения
  • Запомнить пользовательские настройки

Базовый пример

import 'package:shared_preferences/shared_preferences.dart';

// Сохранение данных
future<void> saveUserName(String name) async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.setString('user_name', name);
}

// Чтение данных
Future<String?> getUserName() async {
  final prefs = await SharedPreferences.getInstance();
  return prefs.getString('user_name');
}

Полный пример: Сохранение темы

class ThemePreferences {
  static const String _themeModeKey = 'theme_mode';
  
  // Сохранить тему
  static Future<void> setThemeMode(bool isDarkMode) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setBool(_themeModeKey, isDarkMode);
  }
  
  // Получить тему
  static Future<bool> getThemeMode() async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getBool(_themeModeKey) ?? false; // по умолчанию light
  }
  
  // Очистить
  static Future<void> clearTheme() async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.remove(_themeModeKey);
  }
}

// Использование
class MyApp extends StatefulWidget {
  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _isDarkMode = false;
  
  @override
  void initState() {
    super.initState();
    _loadTheme();
  }
  
  Future<void> _loadTheme() async {
    final isDark = await ThemePreferences.getThemeMode();
    setState(() {
      _isDarkMode = isDark;
    });
  }
  
  Future<void> _toggleTheme() async {
    _isDarkMode = !_isDarkMode;
    await ThemePreferences.setThemeMode(_isDarkMode);
    setState(() {});
  }
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: _isDarkMode ? ThemeData.dark() : ThemeData.light(),
      home: Scaffold(
        appBar: AppBar(title: Text('Theme Toggle')),
        body: Center(
          child: ElevatedButton(
            onPressed: _toggleTheme,
            child: Text(_isDarkMode ? 'Light Mode' : 'Dark Mode'),
          ),
        ),
      ),
    );
  }
}

Пример: Сохранение данных пользователя

class UserPreferences {
  static const String _userIdKey = 'user_id';
  static const String _userEmailKey = 'user_email';
  static const String _userNameKey = 'user_name';
  static const String _userAgeKey = 'user_age';
  
  // Модель пользователя
  static Future<void> saveUser({
    required String id,
    required String email,
    required String name,
    required int age,
  }) async {
    final prefs = await SharedPreferences.getInstance();
    await Future.wait([
      prefs.setString(_userIdKey, id),
      prefs.setString(_userEmailKey, email),
      prefs.setString(_userNameKey, name),
      prefs.setInt(_userAgeKey, age),
    ]);
  }
  
  // Получить пользователя
  static Future<Map<String, dynamic>> getUser() async {
    final prefs = await SharedPreferences.getInstance();
    return {
      'id': prefs.getString(_userIdKey) ?? '',
      'email': prefs.getString(_userEmailKey) ?? '',
      'name': prefs.getString(_userNameKey) ?? '',
      'age': prefs.getInt(_userAgeKey) ?? 0,
    };
  }
  
  // Очистить данные (logout)
  static Future<void> clearUser() async {
    final prefs = await SharedPreferences.getInstance();
    await Future.wait([
      prefs.remove(_userIdKey),
      prefs.remove(_userEmailKey),
      prefs.remove(_userNameKey),
      prefs.remove(_userAgeKey),
    ]);
  }
}

// Использование
class UserProfileScreen extends StatefulWidget {
  @override
  State<UserProfileScreen> createState() => _UserProfileScreenState();
}

class _UserProfileScreenState extends State<UserProfileScreen> {
  late Map<String, dynamic> _user;
  bool _isLoading = true;
  
  @override
  void initState() {
    super.initState();
    _loadUser();
  }
  
  Future<void> _loadUser() async {
    final user = await UserPreferences.getUser();
    setState(() {
      _user = user;
      _isLoading = false;
    });
  }
  
  Future<void> _logout() async {
    await UserPreferences.clearUser();
    // Переход на страницу логина
  }
  
  @override
  Widget build(BuildContext context) {
    if (_isLoading) {
      return Scaffold(
        appBar: AppBar(title: Text('Profile')),
        body: Center(child: CircularProgressIndicator()),
      );
    }
    
    return Scaffold(
      appBar: AppBar(title: Text('Profile')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Name: ${_user['name']}'),
            Text('Email: ${_user['email']}'),
            Text('Age: ${_user['age']}'),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _logout,
              style: ElevatedButton.styleFrom(
                backgroundColor: Colors.red,
              ),
              child: Text('Logout'),
            ),
          ],
        ),
      ),
    );
  }
}

Пример: Сохранение списка (JSON)

import 'dart:convert';

class Todo {
  final String id;
  final String title;
  final bool completed;
  
  Todo({required this.id, required this.title, this.completed = false});
  
  Map<String, dynamic> toJson() => {
    'id': id,
    'title': title,
    'completed': completed,
  };
  
  factory Todo.fromJson(Map<String, dynamic> json) {
    return Todo(
      id: json['id'] as String,
      title: json['title'] as String,
      completed: json['completed'] as bool? ?? false,
    );
  }
}

class TodoStorage {
  static const String _todosKey = 'todos';
  
  // Сохранить список todos
  static Future<void> saveTodos(List<Todo> todos) async {
    final prefs = await SharedPreferences.getInstance();
    final jsonString = jsonEncode(
      todos.map((todo) => todo.toJson()).toList(),
    );
    await prefs.setString(_todosKey, jsonString);
  }
  
  // Получить список todos
  static Future<List<Todo>> getTodos() async {
    final prefs = await SharedPreferences.getInstance();
    final jsonString = prefs.getString(_todosKey);
    
    if (jsonString == null) return [];
    
    final jsonList = jsonDecode(jsonString) as List;
    return jsonList
        .map((item) => Todo.fromJson(item as Map<String, dynamic>))
        .toList();
  }
  
  // Добавить todo
  static Future<void> addTodo(Todo todo) async {
    final todos = await getTodos();
    todos.add(todo);
    await saveTodos(todos);
  }
  
  // Удалить todo
  static Future<void> removeTodo(String id) async {
    final todos = await getTodos();
    todos.removeWhere((t) => t.id == id);
    await saveTodos(todos);
  }
}

// Использование
class TodoListScreen extends StatefulWidget {
  @override
  State<TodoListScreen> createState() => _TodoListScreenState();
}

class _TodoListScreenState extends State<TodoListScreen> {
  late Future<List<Todo>> _todosFuture;
  
  @override
  void initState() {
    super.initState();
    _todosFuture = TodoStorage.getTodos();
  }
  
  Future<void> _addTodo(String title) async {
    final newTodo = Todo(
      id: DateTime.now().toString(),
      title: title,
    );
    await TodoStorage.addTodo(newTodo);
    setState(() {
      _todosFuture = TodoStorage.getTodos();
    });
  }
  
  Future<void> _removeTodo(String id) async {
    await TodoStorage.removeTodo(id);
    setState(() {
      _todosFuture = TodoStorage.getTodos();
    });
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Todos')),
      body: FutureBuilder<List<Todo>>(
        future: _todosFuture,
        builder: (context, snapshot) {
          if (!snapshot.hasData) {
            return Center(child: CircularProgressIndicator());
          }
          
          final todos = snapshot.data!;
          
          return ListView.builder(
            itemCount: todos.length,
            itemBuilder: (context, index) {
              final todo = todos[index];
              return ListTile(
                title: Text(todo.title),
                trailing: IconButton(
                  icon: Icon(Icons.delete),
                  onPressed: () => _removeTodo(todo.id),
                ),
              );
            },
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => _addTodo('New Todo'),
        child: Icon(Icons.add),
      ),
    );
  }
}

Типы данных SharedPreferences

final prefs = await SharedPreferences.getInstance();

// String
await prefs.setString('name', 'John');
String? name = prefs.getString('name');

// int
await prefs.setInt('age', 30);
int? age = prefs.getInt('age');

// double
await prefs.setDouble('height', 1.75);
double? height = prefs.getDouble('height');

// bool
await prefs.setBool('isDarkMode', true);
bool? isDark = prefs.getBool('isDarkMode');

// List<String>
await prefs.setStringList('tags', ['flutter', 'dart']);
List<String>? tags = prefs.getStringList('tags');

// Удаление
await prefs.remove('name');

// Очистка всех данных
await prefs.clear();

Лучшие практики

1. Используй константы для ключей

class StorageKeys {
  static const String userId = 'user_id';
  static const String userEmail = 'user_email';
  static const String isDarkMode = 'is_dark_mode';
}

// Использование
await prefs.setString(StorageKeys.userId, '123');

2. Оборачивай в сервис класс

class LocalStorageService {
  static final LocalStorageService _instance = LocalStorageService._internal();
  
  factory LocalStorageService() => _instance;
  LocalStorageService._internal();
  
  late SharedPreferences _prefs;
  
  Future<void> init() async {
    _prefs = await SharedPreferences.getInstance();
  }
  
  Future<void> setString(String key, String value) async {
    await _prefs.setString(key, value);
  }
  
  String? getString(String key) => _prefs.getString(key);
}

3. Обработка ошибок

Future<void> saveData(String key, String value) async {
  try {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(key, value);
  } catch (e) {
    print('Error saving data: $e');
  }
}

Когда использовать SharedPreferences

Настройки приложения (тема, язык) ✅ Данные пользователя (имя, email) ✅ Состояние UI (прокрутка, выбранный tab) ✅ Токены аутентификации (не рекомендуется, лучше использовать secure storage) ✅ Кеш небольших данных

Большие объемы данных — используй базу данных ❌ Чувствительные данные — используй flutter_secure_storage ❌ Сложные структуры — используй Hive или SQLite

Вывод

SharedPreferences — это простой и удобный способ сохранять локальные данные в Flutter. Идеален для:

  • Пользовательских настроек
  • Простого состояния приложения
  • Кеша часто используемых данных

Для более сложных сценариев используй Hive (для больших данных) или flutter_secure_storage (для чувствительных данных).

Приведи пример использования SharedPreferences | PrepBro