【问题标题】:How to save timeline list of events in flutter?如何在颤动中保存事件的时间线列表?
【发布时间】:2021-02-07 05:00:17
【问题描述】:

我尝试使用flutter时间线包,但我没有成功保存和加载带有sharedpreference的事件列表

https://pub.dev/packages/flutter_timeline

这是我的代码和我期望做的事情

[Edit] 这里是我认为我需要但不需要添加的 futur builder 的代码

import 'package:flutter/material.dart';
import 'package:flutter_timeline/flutter_timeline.dart';
import 'package:flutter_timeline/indicator_position.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';


void main() {
  runApp(TimelineDemoApp());
}

class TimelineDemoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Timeline',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),

      home: PlainTimelineDemoScreen(),
    );
  }
}




class PlainTimelineDemoScreen extends StatefulWidget {

  @override
  State<StatefulWidget> createState() => _PlainTimelineDemoScreenState();
}

class _PlainTimelineDemoScreenState extends State<PlainTimelineDemoScreen> {
  List<TimelineEventDisplay> events;

  @override
  void initState() {
    initializeDateFormatting("fr_FR", null);

    super.initState();
    load_timeline();
    events = [
      plainEventDisplay,
    ];
  }


  String Data1;
  String Data2;

  save_timeline() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      prefs.setString('timeline', events);
    });
  }
  
  load_timeline() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {

      events = prefs.getString('timeline');
    });

  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Timeline test"),
      ),
      body:  FutureBuilder(
        future: load_timeline(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return _buildTimeline();
          }
          return CircularProgressIndicator(); // or some other widget
        },
      ),

      floatingActionButton: FloatingActionButton(
        onPressed: _addEvent,
        child: Icon(Icons.add),
      ),
    );
  }




  TimelineEventDisplay get plainEventDisplay {
    var currentTime = DateFormat('dd-MM-yyyy').format(DateTime.now());


    return TimelineEventDisplay(
      anchor: IndicatorPosition.top,
      indicatorOffset: Offset(0, 0),
      child: TimelineEventCard(
          title: Text("${currentTime}"),
          content:  Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text("description1 : $Data1"),  
              Text("description2 : $Data2"),


            ],
          )
      ),
      indicator:       TimelineDots.of(context).circleIcon,
    );
  }


  Widget _buildTimeline() {
    return TimelineTheme(
        data: TimelineThemeData(
            lineColor: Colors.blueAccent, itemGap: 5, lineGap: 0),
        child: Timeline(
          anchor: IndicatorPosition.center,
          indicatorSize: 56,
          altOffset: Offset(10, 10),
          events: events,
        ));
  }

  void _addEvent() {
    setState(() {
      //currently in this example data1 and data2 or static
      //after, here user will modify Data1 and data2 with textfield and save is text in save_timeline()
      save_timeline();
      events.add(plainEventDisplay);

    });
  }
}

【问题讨论】:

  • 我认为这个问题需要更多的关注。或许可以用更简短、更清晰的方式重新表述问题。

标签: flutter


【解决方案1】:

List&lt;TimelineEventDisplay&gt; 直接转换为/从String 不起作用:

List<TimelineEventDisplay> events;
...
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('timeline', events);
...
events = prefs.getString('timeline');

您需要一种方法来序列化/反序列化有关事件的相关数据。 在您的情况下,这些似乎是事件的日期时间和两个描述。

您可以使用类对它们进行建模,并包含用于将对象与 JSON 转换为/从 JSON 转换的支持函数:

class EventData {
  final DateTime dateTime;
  final String data1;
  final String data2;

  EventData(this.dateTime, this.data1, this.data2);

  EventData.fromJson(Map<String, dynamic> json)
      : dateTime = DateTime.parse(json['dateTime']),
        data1 = json['data1'],
        data2 = json['data2'];

  Map<String, dynamic> toJson() => {
    'dateTime': dateTime.toIso8601String(),
    'data1': data1,
    'data2': data2,
  };
}

然后您可以将有关事件的数据保存为List&lt;EventData&gt; eventsData

save_timeline 函数中将事件数据存储为 JSON:

SharedPreferences prefs = await SharedPreferences.getInstance();
var json = jsonEncode(eventsData);
prefs.setString('timeline', json);

load_timeline 函数中从 JSON 加载事件数据:

SharedPreferences prefs = await SharedPreferences.getInstance();
var json = prefs.getString('timeline');
var items = jsonDecode(json) as List;
eventsData = items.map((i) => EventData.fromJson(i)).toList();

最后,当您想要显示事件时,您可以使用plainEventDisplay 函数将每个EventData 渲染为TimelineEventDisplay

完整示例:

import 'package:flutter/material.dart';
import 'package:flutter_timeline/flutter_timeline.dart';
import 'package:flutter_timeline/indicator_position.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';

void main() {
  runApp(TimelineDemoApp());
}

class TimelineDemoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Timeline',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: PlainTimelineDemoScreen(),
    );
  }
}

class PlainTimelineDemoScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _PlainTimelineDemoScreenState();
}

class _PlainTimelineDemoScreenState extends State<PlainTimelineDemoScreen> {
  List<EventData> eventsData;
  List<TimelineEventDisplay> events;

  @override
  void initState() {
    super.initState();
    initializeDateFormatting("fr_FR", null);
  }

  String Data1;
  String Data2;

  save_timeline() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    //serialize event data to json
    var json = jsonEncode(eventsData);
    await prefs.setString('timeline', json);
  }

  load_timeline() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    var json = prefs.getString('timeline');
    if (json == null) {
      //no data available
      eventsData = [];
    } else {
      //deserialize event data from json
      var items = jsonDecode(json) as List;
      eventsData = items.map((i) => EventData.fromJson(i)).toList();
    }
    //render event data
    events = eventsData.map(plainEventDisplay).toList();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Timeline test"),
      ),
      body: FutureBuilder(
        future: load_timeline(),
        builder: (context, snapshot) {
          return _buildTimeline();
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _addEvent,
        child: Icon(Icons.add),
      ),
    );
  }

  TimelineEventDisplay plainEventDisplay(EventData eventData) {
    var formattedTime = DateFormat('dd-MM-yyyy').format(eventData.dateTime);

    return TimelineEventDisplay(
      anchor: IndicatorPosition.top,
      indicatorOffset: Offset(0, 0),
      child: TimelineEventCard(
          title: Text("${formattedTime}"),
          content: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text("description1 : ${eventData.data1}"),
              Text("description2 : ${eventData.data2}"),
            ],
          )),
      indicator: TimelineDots.of(context).circleIcon,
    );
  }

  Widget _buildTimeline() {
    return TimelineTheme(
        data: TimelineThemeData(
            lineColor: Colors.blueAccent, itemGap: 5, lineGap: 0),
        child: Timeline(
          anchor: IndicatorPosition.center,
          indicatorSize: 56,
          altOffset: Offset(10, 10),
          events: events,
        ));
  }

  void _addEvent() {
    //currently in this example data1 and data2 or static
    //after, here user will modify Data1 and data2 with textfield and save is text in save_timeline()
    Data1 = "data1 from " + DateTime.now().toIso8601String();
    Data2 = "data2 from " + DateTime.now().toIso8601String();
    var eventData = EventData(DateTime.now(), Data1, Data2);
    eventsData.add(eventData);
    save_timeline();
    //trigger refresh
    setState(() {});
  }
}

class EventData {
  final DateTime dateTime;
  final String data1;
  final String data2;

  EventData(this.dateTime, this.data1, this.data2);

  EventData.fromJson(Map<String, dynamic> json)
      : dateTime = DateTime.parse(json['dateTime']),
        data1 = json['data1'],
        data2 = json['data2'];

  Map<String, dynamic> toJson() => {
    'dateTime': dateTime.toIso8601String(),
    'data1': data1,
    'data2': data2,
  };
}

【讨论】:

  • 哇,谢谢,它工作得很好,我现在将开始使用它
猜你喜欢
  • 2019-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-12
  • 2020-11-14
  • 1970-01-01
  • 2019-10-09
  • 1970-01-01
相关资源
最近更新 更多