Flutter - сохранение пользовательских данных - PullRequest
0 голосов
/ 21 декабря 2018

В настоящее время я создаю приложение, которое отслеживает общие криптографические данные, наряду с этими данными мы также публикуем новостные статьи, предназначенные для энтузиастов крипто.Каждый аспект данных этой новостной статьи хранится в строковой форме, от URL изображения до даты публикации - полный список ниже .

Я ищу способ сохранить эти данные на устройстве пользователя.В идеальной ситуации я просто сохранил бы эти данные в массиве JSON, но, не зная, как это сделать, я не уверен, что это самый эффективный способ сохранить эти данные для последующего отображения.

Если вы решите, что JSON будет лучшим способом сохранения этих данных, все, что мне нужно знать, - это как правильно управлять этими данными в массиве различных сохраненных статей и как правильно импортировать их в мой код Dart.

Пример этого кода был бы великолепен, я собираюсь опубликовать это приложение до нового года, поэтому мне нужна вся помощь, которую я могу получить.Большое спасибо.

Это вышеупомянутые данные, которые я хочу сохранить / отобразить из этого источника :

  • Источник - source
  • Автор - author
  • Описание - description
  • Дата публикации - publishedAt
  • Название статьи - title
  • URL дляСтатья - url
  • Изображение статьи - urlToImage

Редактировать : попытка переделать ответ shadowsheep, чтобы он соответствовал индексной модели

Каждый виджет новостей - это новый inkwell, который позволяет создавать новый scaffold.Из этого scaffold вам предоставляется возможность сохранить статью.При сохранении код в настоящее время просто изменяет значение следующих строк с title, description, URL и Image 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,
)

1 Ответ

0 голосов
/ 21 декабря 2018

Если вы хотите сохранить данные в виде кода Dart и иметь возможность использовать его на Android и iOS, я предлагаю вам sqlite плагин , подобный этому:

https://github.com/tekartik/sqflite

В противном случае, если вам нужно только сохранить кучу данных, используйте плагин shared_preferences

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

Оба эти плагина поддерживают как Android, так иiOS

Вы запрашиваете много кода ^ _ ^ (не так).

Итак, прежде всего вам нужно получить свой JSON через HTTP-вызов.Для этого используйте 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 вы получитеfull JSON.

Теперь вам нужно сериализовать, и я предлагаю вам это действительно хорошее чтение .

Я выбрал для этого ответаManaul JSON Decoding

Ручное JSON-декодирование относится к использованию встроенного JSON-декодера в dart: convert.Он включает передачу необработанной строки JSON в метод json.decode (), а затем поиск значений, которые вам нужны в Map, которую возвращает метод.У него нет внешних зависимостей или определенного процесса установки, и это хорошо для быстрого подтверждения концепции.

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

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

Теперь, когда у нас есть статьи, мы попытаемся сохранить их на Sqlite DB через пакет Sqflite * 1047.*

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 Serailization и поэкспериментируйте с моим кодом и попытайтесь добавить некоторые другие лучшие практики, которые могут лучше соответствовать вашим потребностям.Это просто быстрая игровая площадка, чтобы, ну, в общем, поиграть.

Итак, я остановился на этом методе:

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

enter image description here

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...