flutter - Flutter 中使用 SharedPreferences 的动态列表

标签 flutter dart sharedpreferences

Hello, I'm trying to make an app where I can store data inputted by the user like this one. My task is to use SharedPreferences to store the data.

Main Screen

I used SharedPreferences to save the data in a List

saveData() async {
List<String> itemData = [];
itemData.add(fstcontroller.text);
itemData.add(sndcontroller.text);
itemData.add(trdcontroller.text);
itemData.add(fthcontroller.text);

SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setStringList("item", itemData);
}

I have 2 problems, First Problem: whenever I click the Show Cart button, it shows this one

Second Screen

I don't want to display like this, I want to only display the "Item Brand", the rest will not be displayed. Then, if I click the cell, it will display the full details of the item in the third screen.

here's the SecondScreen

class SecondScreen extends StatefulWidget {
    @override
    State createState() => new DynamicList();
 }

class DynamicList extends State<SecondScreen> {
  List<String> listItems = [];

  @override
  void initState() {
    super.initState();
    getUser();
 }

 getUser() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    var itemData = prefs.getStringList("item");
    setState(() {
      listItems = itemData;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: Column(
        children: <Widget>[
          Expanded(
            child: ListView.builder(
                itemCount: listItems.length, itemBuilder: buildList),
          )
        ],
      ),
    );
  }

  Widget buildList(BuildContext context, int index) {
    return Container(
      margin: EdgeInsets.all(4),
      decoration: BoxDecoration(
          border: Border.all(
            color: Colors.black,
            width: 2,
          ),
          borderRadius: BorderRadius.circular(5)),
      child: ListTile(
        title: Text(listItems[index]),
      ),
    );
  }
  }

Second problem: Whenever I add multiple data, the data doesn't stack. It only replaces the data.

最佳答案

我认为您需要重新考虑如何存储和读取数据。

现在,您将在键“item”下存储四个字段的列表,因此每次存储数据时,都会通过将 4 个项目字段放入列表中来删除“item”。

虽然我不确定共享首选项是最好的方法,但您可以执行以下操作: 将四个字段作为 json 序列化,并将每个 json 字符串存储在列表中。

对于第二个问题, 存储它时,您应该首先检索现有列表并更新该列表,然后再将其存储回来。

var itemData = prefs.getStringList("item")

然后将新项目添加到列表中:

itemData.add(newItem)

存储更新后的列表

prefs.setStringList("item", itemData);

现在,当您检索列表时,您将检索 json 字符串

使用 json 导入'dart:convert'; 然后使用 jsonDecode(stringJson) 从共享首选项中的 listItem 获取 kson,并在存储之前使用 jsonEncode(jsonObject) 将对象编码为字符串。

对于第一个问题,一旦你有了 json,你就可以访问这样的字段: jsonItem['品牌']

Ps,我在智能手机上,无法为您编写完整的代码。也许稍后

编辑:现在我回到家了。 对于 json 对象,最少地修改您的代码(未经测试):

saveData() async {
final Map<String, String> item = Map<String, String>();
item['brand'] = fstcontroller.text;
item['size'] = sndcontroller.text);
item['quantity'] = trdcontroller.text);
item['color'] = fthcontroller.text);

SharedPreferences prefs = await SharedPreferences.getInstance();
List<String> cart = prefs.getStringList("cart");
if (cart == null) cart = [];
cart.add(jsonEncode(item));
prefs.setStringList("cart", cart);
}

然后你的第二个屏幕的代码变成(再次未经测试 - 我的更改已注释):

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

class SecondScreen extends StatefulWidget {
  @override
  State createState() => new DynamicList();
}

class DynamicList extends State<SecondScreen> {
// I changed the type of your list
  List<Map<String, String>> listItems = [];

  @override
  void initState() {
    super.initState();
    getUser();
  }

  getUser() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
//I chaged these lines to retrieve the cart instead
    final cart = prefs.getStringList("cart")!;
    setState(() {
//convert the string cart List back to a list of objects:
      cart.forEach((item) {
        listItems.add(jsonDecode(item));
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: Column(
        children: <Widget>[
          Expanded(
            child: ListView.builder(
                itemCount: listItems.length, itemBuilder: buildList),
          )
        ],
      ),
    );
  }

  Widget buildList(BuildContext context, int index) {
    return Container(
      margin: EdgeInsets.all(4),
      decoration: BoxDecoration(
          border: Border.all(
            color: Colors.black,
            width: 2,
          ),
          borderRadius: BorderRadius.circular(5)),
      child: ListTile(
// Only use the 'brand' field as title of your list
        title: Text(listItems[index]['brand']!),
      ),
    );
  }
}

关于flutter - Flutter 中使用 SharedPreferences 的动态列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67244783/

相关文章:

flutter - flutter :使页面导航手势与自定义手势共存

java - 如何从服务检索偏好数据

java - Android:在应用程序启动之间存储有序值列表

ios - 为什么不能将子 <Widget>[] 放入 body : Center widget?

Dart 如何创建一个可以接受任意数量参数的函数

android - 以编程方式单击主页按钮并在 flutter 中关闭屏幕

firebase - 如何将Flutter中从Firebase DocumentSnapshot获得的List <dynamic>中的值复制到新的List中并为其添加值?

Android:在震动监听器类中使用 SharedPreferences

android-studio - 我无法在 Android Studio 和 Flutter 中创建目录/文件夹,只能创建包

android - 如何以编程方式将文本元素添加到我的小部件/类?