Flutter-保存用户数据 [英] Flutter - Saving user data

查看:116
本文介绍了Flutter-保存用户数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在创建一个应用程序,该应用程序可以跟踪常规的加密数据,并与这些数据一起发布针对加密爱好者的新闻报道。该新闻文章数据的各个方面都以字符串形式存储,从图片网址到发布日期-下面的完整列表



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



如果您认为JSON是保存此数据的最佳方法,那么我只需要知道如何正确地将数据管理到一系列不同的已保存文章中,以及如何将其导入正确地放入我的Dart代码中



此代码示例很好,我希望在新年之前发布此应用,因此我需要获得所有帮助。非常感谢。



这是我希望从




I'm currently creating an application that tracks general crypto data, along with this data we also post news articles tailored to crypto enthusiasts. Every aspect of this news article data is stored in string form, from image url to date published - full list below.

I'm looking for a way to save this data to the user's device. In a perfect situation I'd just have this data saved in a JSON array, but apart from not knowing how to perform this, I'm not sure if it's the most efficient way to save this data for later display.

If you decide that JSON would be the best way of saving this data, all I need to know is how to properly manage this data into an array of different saved articles and how to import this properly into my Dart code.

An example of this code would be great, I'm looking to publish this app before the new year so I need all the help I can get. Many thanks.

This is the aforementioned data I'm looking to save / display from this source:

  • Source - source
  • Author - author
  • Description - description
  • Date Published - publishedAt
  • Article Title - title
  • Url to Article - url
  • Article Image - urlToImage

Edit: Trying to rework shadowsheep's answer to fit an index model

Each news widget is a new inkwell that allows a new scaffold to be built. From this scaffold you are presented with the option to save the article. On saving, the code currently just changes the value of the following strings with the title, description, URL and Image URL.

  • _sTitle
  • _sDescription
  • _sURL
  • _sURLtoImage

I would really like a way of having the database, as described by shadowsheep, saved to the user's device. This means that the saved articles will become persistent on the device despite the user closing and opening the app.

The following code is the exact use case in which I'm displaying my news data.

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,
)

解决方案

If you want to save data in a persitance way in Dart code and be able to use it on Android and iOS I suggest you an sqlite plugin like that:

https://github.com/tekartik/sqflite

Otherwise if you only need to save a bunch of data use the shared_preferences plugin

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

These two plugins both support either Android and iOS

You are requesting a lot of code ^_^ (ain't it).

So first of all you need to get your json through an HTTP call. For that use the 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);

Wrap it up in an async method:

void _jsonAndSqlite() async {
...
}

And in the response variable you have your full JSON.

Now you need to serialize and I suggest you this really good reading.

I've choose for this answer the Manaul JSON Decoding

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());

Now that we have articles will try to save them on Sqlite DB through Sqflite package

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');
});

And that's it! Have fun studing and coding. Read the articles I've posted for you for JSON serailization and play around with my code, and trying to adding some other best practices they may better fit your needs. This is just a quick playground to, well, play with.

So I ended up with this method:

[...]
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');
    });
  }

这篇关于Flutter-保存用户数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆