草庐IT

json - Flutter - 保存用户数据

coder 2023-07-22 原文

我目前正在创建一个跟踪一般加密数据的应用程序,除了这些数据,我们还发布为加密爱好者量身定制的新闻文章。此新闻文章数据的每个方面都以字符串形式存储,从图像 url 到发布日期 - 下面的完整列表

我正在寻找将此数据保存到用户设备的方法。在理想情况下,我只是将此数据保存在 JSON 数组中,但除了不知道如何执行此操作之外,我不确定这是否是保存此数据以供以后显示的最有效方法。

如果您认为 JSON 是保存这些数据的最佳方式,我只需要知道如何将这些数据正确地管理到不同保存文章的数组中,以及如何将其正确地导入到我的 Dart 代码中。

这段代码的示例会很棒,我希望在新的一年之前发布此应用程序,因此我需要我能获得的所有帮助。非常感谢。

这是我要从 this source 中保存/显示的上述数据:

  • 来源 - 来源
  • 作者 - 作者
  • 描述 - 描述
  • 发布日期 - publishedAt
  • 文章标题 - title
  • 文章网址 - url
  • 文章图片 - urlToImage

编辑:尝试修改 shadowsheep 的答案以适应索引模型

每个新闻小部件都是一个新的 inkwell,它允许构建一个新的 scaffold。从这个 scaffold 中,您会看到保存文章的选项。保存时,代码目前仅更改以下字符串的值:titledescriptionURLImage URL.

  • _sTitle
  • _sDescription
  • _sURL
  • _sURLtoImage

我非常想要一种将数据库(如 shadowsheep 所述)保存到用户设备的方法。这意味着即使用户关闭和打开应用程序,已保存的文章也将永久保留在设备上。

以下代码是我显示新闻数据的确切用例。

CarouselSlider(
 items: [1,2,3,4,5,6,7,8,9,10].map((index) {
    return  Builder(
      builder: (BuildContext context) {
        return Padding(
          padding:  EdgeInsets.only(
            top: 5.0,
            bottom: 20.0,
          ),
          child:  InkWell(
            borderRadius:  BorderRadius.only(
              topLeft: const Radius.circular(15.0),
              topRight: const Radius.circular(15.0),
            ),
            onTap: () {
              print('Opened article scaffold: "' + articles[index].title + "\"");
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) =>  Scaffold(
                    resizeToAvoidBottomPadding: false,
                    appBar:  AppBar(
                      backgroundColor: const Color(0xFF273A48),
                      elevation: 0.0,
                      title: Container(
                        width: _width*0.90,
                        height: 30,
                        padding: const EdgeInsets.only(
                          bottom: 5,
                          top: 5,
                          left: 10,
                          right: 10,
                        ),
                        decoration:  BoxDecoration(
                          color: Colors.white,
                          borderRadius:  BorderRadius.all(
                              Radius.circular(10.0),
                          ),
                        ),
                        alignment: Alignment.center,
                        child:  AutoSizeText(
                          'Published ' +  DateFormat.yMMMd().format(DateTime.parse(articles[index].publishedAt)) + ", "+ DateFormat.jm().format(DateTime.parse(articles[index].publishedAt)),
                          overflow: TextOverflow.ellipsis,
                          maxLines: 1,
                          minFontSize: 5,
                          maxFontSize: 20,
                          textAlign: TextAlign.center,
                          style:  TextStyle(
                            color: Colors.black,
                            fontFamily: 'Poppins',
                          ),
                        ),
                      ),
                    ),
                    body: Center(
                      child:  Scaffold(
                        resizeToAvoidBottomPadding: false,
                        body: Center(
                          child: Container(
                            decoration:  BoxDecoration(
                              gradient:  LinearGradient(
                                begin: Alignment.topCenter,
                                end: Alignment.bottomCenter,
                                colors: [
                                  const Color(0xFF273A48),
                                  Colors.blueGrey
                                ],
                              ),
                            ),
                            padding: const EdgeInsets.only(
                              top: 20,
                              left: 10,
                              right: 10,
                              bottom: 50
                            ),
                            child:  Column(
                              mainAxisAlignment: MainAxisAlignment.spaceBetween,
                              children: <Widget>[
                                  Column(
                                  mainAxisAlignment: MainAxisAlignment.start,
                                  children: <Widget>[
                                      FutureBuilder<Null>(future: _launched, builder: _launchStatus),
                                      AutoSizeText(
                                      articles[index].title,
                                      overflow: TextOverflow.ellipsis,
                                      textAlign: TextAlign.center,
                                      maxFontSize: 30,
                                      minFontSize: 15,
                                      maxLines: 3,
                                      style:  TextStyle(
                                        color: Colors.white,
                                        fontFamily: 'Poppins',
                                      ),
                                    ),
                                      Divider(
                                      color: Colors.transparent,
                                      height: 15.0,
                                    ),
                                    Container(
                                      decoration:  BoxDecoration(
                                        borderRadius:  BorderRadius.circular(15.0),
                                        color: Colors.transparent,
                                        boxShadow: [
                                            BoxShadow(
                                            color: Colors.black.withAlpha(70),
                                            blurRadius: 50.0,
                                          )
                                        ],
                                        image:  DecorationImage(
                                          image:  NetworkImage(articles[index].urlToImage),
                                          fit: BoxFit.fitHeight,
                                        ),
                                      ),
                                      height: 220,
                                      width: 317.5,
                                    ),
                                      Divider(
                                      color: Colors.transparent,
                                      height: 15.0,
                                    ),
                                  ],
                                ),
                                Container(
                                  padding: const EdgeInsets.only(
                                    left: 20,
                                    right: 20
                                  ),
                                  decoration:  BoxDecoration(
                                    color: Colors.transparent,
                                    borderRadius:  BorderRadius.all(
                                        Radius.circular(10.0),
                                    ),
                                  ),
                                  child:  AutoSizeText(
                                    articles[index].description,
                                    overflow: TextOverflow.ellipsis,
                                    textAlign: TextAlign.center,
                                    maxFontSize: 30,
                                    minFontSize: 10,
                                    maxLines: 10,
                                    style:  TextStyle(
                                      color: Colors.white,
                                      fontFamily: 'Poppins',
                                    ),
                                  ),
                                  width: _width*0.90,
                                  height: _height*0.20,
                                ),
                                Container(
                                  padding: const EdgeInsets.all(4.0),
                                  decoration:  BoxDecoration(
                                    color: const Color(0xFF273A48),
                                    borderRadius:  BorderRadius.all(
                                        Radius.circular(10.0),
                                    ),
                                  ),
                                  child: Row(
                                    mainAxisSize: MainAxisSize.min,
                                    mainAxisAlignment: MainAxisAlignment.center,
                                    children: <Widget>[
                                        IconButton(
                                        icon:  Icon(
                                          Icons.favorite_border,
                                          color: Colors.red
                                        ),
                                        iconSize: 35.0,
                                        onPressed: () {
                                          _sTitle = articles[index].title;
                                          _sDescription = articles[index].description;
                                          _sURL = articles[index].url;
                                          _sURLtoImage = articles[index].urlToImage;
                                          Navigator.push(
                                          context,
                                          MaterialPageRoute(builder: (context) => _favoritesScreen())
                                          );
                                        }
                                      ),
                                        IconButton(
                                        icon:  Icon(
                                          Icons.mobile_screen_share,
                                          color: Colors.white,
                                        ),
                                        iconSize: 35.0,
                                        onPressed: () {
                                          Share.share(
                                            articles[index].title + "\n\nCheck out this article at:\n" + articles[index].url + "\n\nLearn more with Cryp - Tick Exchange",
                                          );
                                        }
                                      ),
                                        IconButton(
                                        icon:  Icon(Icons.launch, color: Colors.lightBlueAccent),
                                        iconSize: 32.5,
                                        onPressed: () => setState(() { _launched = _launchInWebViewOrVC(articles[index].url);}),
                                      ),
                                    ],
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ),
                      ),
                    ),
                  )
                )
              );
            },
            child: Container(
              decoration:  BoxDecoration(
                borderRadius:  BorderRadius.circular(10.0),
                color: const Color(0xFF273A48),
                boxShadow: [
                    BoxShadow(
                    color: Colors.black.withAlpha(70),
                    offset: const Offset(5.0, 5.0),
                    blurRadius: 12.5,
                  )
                ],
                image:  DecorationImage(
                  alignment: Alignment.topCenter,
                  image:  NetworkImage(articles[index].urlToImage),
                  fit: BoxFit.cover,
                ),
              ),
              height: _height*0.35,
              width: _width*0.725,
              child:  Stack(
                children: <Widget>[
                    Align(
                    alignment: Alignment.bottomCenter,
                    child:  Stack(
                      alignment: Alignment.bottomRight,
                      children: <Widget>[
                        Container(
                          padding:  EdgeInsets.only(left: 10.0, right: 10.0),
                          decoration:  BoxDecoration(
                            color: const Color(0xFF273A48),
                            borderRadius:  BorderRadius.only(
                              bottomLeft:  Radius.circular(10.0),
                              bottomRight:  Radius.circular(10.0)
                            ),
                          ),
                          height: 60.0,
                          child:  Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: <Widget>[
                                Flexible(
                                child: Container(
                                  width: _width*0.725,
                                  child:  Text(
                                    articles[index].title,
                                    textAlign: TextAlign.center,
                                    overflow: TextOverflow.ellipsis,
                                    maxLines: 2,
                                    style:  TextStyle(
                                      color: Colors.white,
                                      fontFamily: 'Poppins',
                                      ),
                                    ),
                                ),
                              ),
                                Text(
                                'Published ' +  DateFormat.yMMMd().format(DateTime.parse(articles[index].publishedAt)) + ", "+ DateFormat.jm().format(DateTime.parse(articles[index].publishedAt)),
                                overflow: TextOverflow.ellipsis,
                                maxLines: 1,
                                style:  TextStyle(
                                  color: Colors.blueGrey,
                                  fontSize: 10.0,
                                  fontFamily: 'Poppins',
                              ),
                            ),
                          ],
                        )
                      ),
                      Container(
                        width: 25.0,
                        height: 20.0,
                        alignment: Alignment.center,
                        child:  Text(
                          "$index",
                          textAlign: TextAlign.center,
                          style:  TextStyle(
                            color: Colors.blueGrey,
                            fontSize: 10.0,
                            fontFamily: "Poppins"
                          ),
                        )
                      ),
                      ],
                    ),
                  )
                ],
              ),
            ),
          ),
        );
      },
    );
  }).toList(),
  height: 400,
  autoPlay: true,
)

最佳答案

如果您想在 Dart 代码中以持久的方式保存数据并能够在 Android 和 iOS 上使用它,我建议您使用 sqlite 插件:

https://github.com/tekartik/sqflite

否则,如果您只需要保存一堆数据,请使用shared_preferences 插件

https://github.com/flutter/plugins/tree/master/packages/shared_preferences

这两个插件都支持Android和iOS

您正在请求大量代码 ^_^(不是吗)。

因此,首先您需要通过 HTTP 调用获取您的 json。为此使用 http flutter package :

const request = "https://newsapi.org/v2/top-headlines?sources=crypto-coins-news&apiKey=d40a757cfb2e4dd99fc511a0cbf59098";
http.Response response = await http.get(request);
debugPrint("Response: " + response.body);

将其包装在一个异步方法中:

void _jsonAndSqlite() async {
...
}

response 变量中,您有您的完整 JSON

现在你需要序列化,我建议你这个 really good reading .

我为这个答案选择了手动 JSON 解码

Manual JSON decoding refers to using the built-in JSON decoder in dart:convert. It involves passing the raw JSON string to the json.decode() method, and then looking up the values you need in the Map the method returns. It has no external dependencies or particular setup process, and it’s good for a quick proof of concept.

var myBigJSONObject = json.decode(response.body);
var status = myBigJSONObject['status'];
var totalResults = myBigJSONObject['totalResults'];
var myArticles = myBigJSONObject['articles'];

debugPrint("articles: " + myArticles.toString());

既然我们有文章将尝试通过Sqflite包将它们保存在Sqlite DB上

var myFirstArticle = myArticles[0];
var author = myFirstArticle['author'];
var title = myFirstArticle['title'];

// Get a location using getDatabasesPath
var databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'test.db');

// Delete the database
await deleteDatabase(path);

// open the database
Database database = await openDatabase(path, version: 1,
    onCreate: (Database db, int version) async {
  // When creating the db, create the table
  await db.execute(
      'CREATE TABLE Article (id INTEGER PRIMARY KEY, author TEXT, title TEXT)');
});

// Insert some records in a transaction
await database.transaction((txn) async {
  int id1 = await txn.rawInsert(
      'INSERT INTO Article(author, title) VALUES("$author", "$title")');
  debugPrint('inserted1: $id1');
});

就是这样!享受学习和编码的乐趣。阅读我为您发布的有关 JSON 序列化的文章并尝试使用我的代码,并尝试添加一些其他最佳实践,它们可能更适合您的需求。这只是一个快速的 Playground ,嗯,可以玩。

所以我最终采用了这种方法:

[...]
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';

 [...]
 void _jsonAndSqlite() async {
    const request =
        "https://newsapi.org/v2/top-headlines?sources=crypto-coins-news&apiKey=d40a757cfb2e4dd99fc511a0cbf59098";
    http.Response response = await http.get(request);
    debugPrint("Response: " + response.body);

    var myBigJSONObject = json.decode(response.body);
    var status = myBigJSONObject['status'];
    var totalResults = myBigJSONObject['totalResults'];
    var myArticles = myBigJSONObject['articles'];

    debugPrint("articles: " + myArticles.toString());

    var myFirstArticle = myArticles[0];
    var author = myFirstArticle['author'];
    var title = myFirstArticle['title'];

    // Get a location using getDatabasesPath
    var databasesPath = await getDatabasesPath();
    String path = join(databasesPath, 'test.db');

    // Delete the database
    await deleteDatabase(path);

    // open the database
    Database database = await openDatabase(path, version: 1,
        onCreate: (Database db, int version) async {
      // When creating the db, create the table
      await db.execute(
          'CREATE TABLE Article (id INTEGER PRIMARY KEY, author TEXT, title TEXT)');
    });

    // Insert some records in a transaction
    await database.transaction((txn) async {
      int id1 = await txn.rawInsert(
          'INSERT INTO Article(author, title) VALUES("$author", "$title")');
      debugPrint('inserted1: $id1');
    });
  }

关于json - Flutter - 保存用户数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53889973/

有关json - Flutter - 保存用户数据的更多相关文章

  1. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  2. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  3. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  4. ruby-on-rails - Ruby 检查日期时间是否为 iso8601 并保存 - 2

    我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby​​是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查

  5. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  6. ruby-on-rails - 简单的 Ruby on Rails 问题——如何将评论附加到用户和文章? - 2

    我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。

  7. ruby - RVM "ERROR: Unable to checkout branch ."单用户 - 2

    我在新的Debian6VirtualBoxVM上安装RVM时遇到问题。我已经安装了所有需要的包并使用下载了安装脚本(curl-shttps://rvm.beginrescueend.com/install/rvm)>rvm,但以单个用户身份运行时bashrvm我收到以下错误消息:ERROR:Unabletocheckoutbranch.安装在这里停止,并且(据我所知)没有安装RVM的任何文件。如果我以root身份运行脚本(对于多用户安装),我会收到另一条消息:Successfullycheckedoutbranch''安装程序继续并指示成功,但未添加.rvm目录,甚至在修改我的.bas

  8. ruby-on-rails - 如何使用 Rack 接收 JSON 对象 - 2

    我有一个非常简单的RubyRack服务器,例如:app=Proc.newdo|env|req=Rack::Request.new(env).paramspreq.inspect[200,{'Content-Type'=>'text/plain'},['Somebody']]endRack::Handler::Thin.run(app,:Port=>4001,:threaded=>true)每当我使用JSON对象向服务器发送POSTHTTP请求时:{"session":{"accountId":String,"callId":String,"from":Object,"headers":

  9. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

  10. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

随机推荐