#list #flutter #themes #sharedpreferences
Вопрос:
В моем приложении я хотел бы сохранить список , содержащий ThemeData
bool и строковую переменную. Я пытаюсь сопоставить класс , чтобы сохранить его Shared Preferences
, но при кодировании списка я получаю эту ошибку:
Converting object to an encodable object failed: Instance of 'ThemeData'
Вот класс CustomThemeModel:
class CustomThemeModel {
ThemeData myThemeData = new ThemeData();
String themeName;
bool readOnly = false;
CustomThemeModel({
required this.myThemeData,
required this.themeName,
required this.readOnly,
});
CustomThemeModel.fromMap(Map map) :
this.myThemeData = map['myThemeData'],
this.themeName = map['themeName'],
this.readOnly = map['readOnly'];
Map toMap(){
return{
'myThemeData': this.myThemeData,
'themeName': this.themeName,
'readOnly': this.readOnly,
};
}
}
И метод void, который сохранит список:
void saveData(){
List<String> spList = myThemes.map((e) => json.encode(e.toMap())).toList();
print(spList);
}
Ответ №1:
Вы могли бы попробовать создать свой fromMap
конструктор таким образом.
CustomThemeModel.fromMap(Map map) :
this.myThemeData = map['myThemeData'] as ThemeData,
this.themeName = map['themeName'] as String,
this.readOnly = map['readOnly'] as bool;
Я расскажу немного подробнее в своем основном ответе. В каком случае вы должны преобразовать CustomThemeModel
имеющиеся у вас данные в карту? Чтобы все было просто и чтобы помочь вам решить вашу проблему, я бы предложил сначала разделить вещи логическим способом.
Я предполагаю, что вы хотите иметь список пользовательских тем, поэтому составьте список именно так. Ниже приведен краткий макет, который позволяет вам добавлять в список простым способом и создавать свой список пользовательских тем.
final List<CustomThemeModel> customThemes = [];
void addToCustomThemes(CustomThemeModel model) {
customThemes.add(model);
}
...
InkWell(
onTap: () {
addToCustomThemes(CustomThemeModel(
myThemeData: ThemeData(),
themeName: 'customThemeName1',
readOnly: false,
),
);
}
)
Вы можете довольно легко найти тематическую модель в этом списке.
for (final theme in customThemes) {
return theme.where(theme.themeName == 'my theme name');
}
Edit2: Для вашего конкретного случая использования я бы сделал что — то подобное. Обратите внимание, что код был набран исключительно в текстовом редакторе здесь, поэтому он может не работать без нескольких небольших настроек, но идея есть.
final List<CustomThemeModel> customThemeModels = [
CustomThemeModel(
myThemeData: ThemeData(),
themeName: 'My name',
readOnly: true,
),
// Add all CustomThemeModels here
];
// Create the list of ThemeData from your custom list
final List<ThemeData> themeData = customThemeModels.map((themeModel) {
return themeModel.myThemeData;
}).toList();
Теперь порядок обоих ваших списков одинаков, что позволяет вам найти индекс темы, которую вы хотите использовать, указав имя, которое вы дали.
int getIndex(nameToCheck String) {
return customThemeModels.indexWhere((theme) => theme.themeName == nameToCheck);
}
И затем вы можете использовать этот индекс для предоставления правильного индекса вашему пакету.
Комментарии:
1. Это сработало, но теперь, если я хочу использовать сохраненные данные с помощью fromMap, я получаю такую ошибку: Необработанное исключение: тип ‘String’ не является подтипом типа ‘ThemeData’ в приведении типа
2. С вашим методом что-то не совсем в порядке
saveData
. Вы преобразуете свои темы в список строк, но обрабатываете строку как объект json. Таким образом, преобразование пары ключ-значение String: ThemeData в просто необработанную строку (или ключевое значение String: Строка). Почему бы не сделать свой список пользовательских тем просто списком<CustomThemeModel>, помещая каждую новую созданную вами тему в конец списка?3. @KrekZsole Ознакомьтесь с моим редактированием оригинального поста, возможно, это поможет вам вернуться к основам. Использование карт и преобразование в json здесь кажется совершенно ненужным.
4. Вся моя идея заключается в том, что у меня есть класс CustomThemeList, в котором я могу указать данные темы, название темы и указать, доступна ли она только для чтения или нет. Из этого класса я передаю данные тем в список<ThemeData>, потому что плагину, который я использую, нужен список тем для получения тем (плагин stacked_themes). Поэтому в основном я использую класс CustomThemeData только для отображения имени темы и использую список тем для установки темы. Вся эта концепция работает. до тех пор, пока я не захочу их спасти.
5. Я думаю, вам следует поискать решение, в котором вы откажетесь от решения JSON / map, которое у вас было (оно значительно усложняет проблему), и просто сохраните два списка в своем глобальном состоянии. Один из них содержит тематические данные для вашего пакета, а другой содержит пользовательскую модель, которая поможет вам выбрать правильный.