You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SharedPreferences能否存储List<dynamic>?API数据本地存储报错求助

Hey David, let's break down your problem and fix it step by step.

问题根源

First off, SharedPreferences doesn't support storing lists of objects directly. Its setStringList method only accepts List<String> data, but your products variable is a list of Product objects. That's exactly why you're getting the type 'List' is not a subtype of type 'List<String>' error.

解决方案

To store your product list, we need to serialize the objects into JSON strings first, then save them to SharedPreferences. When reading, we'll deserialize those strings back into Product objects. Here are two common approaches:

Approach 1: Convert each object to a JSON string (store as List<String>)

This is great if you need to manipulate individual elements in the list later.

Step 1: Add serialization methods to your Product class

Make sure your Product class can convert between objects and JSON:

class Product {
  final int productID;
  final String name;
  final String description;
  final double costPrice;
  final double salePrice;
  // Add all your other fields here

  Product({
    required this.productID,
    required this.name,
    required this.description,
    required this.costPrice,
    required this.salePrice,
    // Initialize other fields
  });

  // Convert object to JSON map
  Map<String, dynamic> toJson() {
    return {
      'ProductID': productID,
      'Name': name,
      'Description': description,
      'CostPrice': costPrice,
      'SalePrice': salePrice,
      // Map all other fields
    };
  }

  // Convert JSON map back to object
  factory Product.fromJson(Map<String, dynamic> json) {
    return Product(
      productID: json['ProductID'],
      name: json['Name'],
      description: json['Description'],
      costPrice: json['CostPrice'].toDouble(),
      salePrice: json['SalePrice'].toDouble(),
      // Parse all other fields
    );
  }
}

Step 2: Update your save logic

Convert each Product in your list to a JSON string before saving:

Future fetchAllProduct() async{
 try{
   // Note: You were using page=1 every time in the loop—changed to $j to get page 1 and 2
   for(int j = 1; j < 3; j++){
     final response = await http.get(Uri.parse('https://website/api/?page=$j'));
     List<dynamic> result = json.decode(response.body);
     // Convert API response to Product objects first
     List<Product> fetchedProducts = result.map((item) => Product.fromJson(item)).toList();
     products.addAll(fetchedProducts);
   }
   // Save once after the loop (avoid overwriting data repeatedly)
   SharedPreferences preferences = await SharedPreferences.getInstance();
   List<String> productsJson = products.map((product) => json.encode(product.toJson())).toList();
   preferences.setStringList('prds', productsJson);

 }catch (ex){
   print('$ex');
 }
 print(products);
}

Step 3: Read the saved data

Future<List<Product>> loadSavedProducts() async {
  SharedPreferences preferences = await SharedPreferences.getInstance();
  List<String>? savedJsonList = preferences.getStringList('prds');
  if (savedJsonList == null) return [];
  
  // Convert each JSON string back to a Product object
  return savedJsonList.map((jsonStr) => Product.fromJson(json.decode(jsonStr))).toList();
}

Approach 2: Convert the entire list to a single JSON string

If you don't need to modify individual elements, this is a more concise option:

Save logic update

// After fetching all products
SharedPreferences preferences = await SharedPreferences.getInstance();
String productsJson = json.encode(products.map((p) => p.toJson()).toList());
preferences.setString('prds', productsJson);

Read logic

Future<List<Product>> loadSavedProducts() async {
  SharedPreferences preferences = await SharedPreferences.getInstance();
  String? savedJson = preferences.getString('prds');
  if (savedJson == null) return [];
  
  List<dynamic> jsonList = json.decode(savedJson);
  return jsonList.map((item) => Product.fromJson(item)).toList();
}
Quick Note

In your original code, you were requesting page=1 in every loop iteration. I adjusted it to use page=$j so you actually fetch page 1 and 2 data—hope that was what you intended!

内容的提问来源于stack exchange,提问作者David

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:18:21