Flutter 状态管理器正在不断地重建小部件,而不是更新,如何消除这种情况?颤振
因此,我很难理清如何将数据动态添加到我的DataGrid中。我得到了Syncfusion支持部门的帮助,到目前为止,他们表现得非常出色。然而,我仍然无法获得完整和正确的功能 我正在使用GetX GetBuilder包装数据网格。它从数据库接收数据,并应在将数据库添加到时更新此数据。但是,它目前正在连续运行,或者说每秒运行50次。这显然在很多方面都不好。然而,我目前有完整的功能,但它是不正确的 我向GridSource构造函数中抛出了一个print语句,它会连续打印。所以有点不对劲,我想不出来。我尝试过移动构建器(从构建器中移出)以及数据源声明,但是这完全破坏了网格加载的功能 这是完整的演示项目 有人能指出我做错了什么吗 数据网格屏幕:Flutter 状态管理器正在不断地重建小部件,而不是更新,如何消除这种情况?颤振,flutter,datagrid,syncfusion,flutter-getx,Flutter,Datagrid,Syncfusion,Flutter Getx,因此,我很难理清如何将数据动态添加到我的DataGrid中。我得到了Syncfusion支持部门的帮助,到目前为止,他们表现得非常出色。然而,我仍然无法获得完整和正确的功能 我正在使用GetX GetBuilder包装数据网格。它从数据库接收数据,并应在将数据库添加到时更新此数据。但是,它目前正在连续运行,或者说每秒运行50次。这显然在很多方面都不好。然而,我目前有完整的功能,但它是不正确的 我向GridSource构造函数中抛出了一个print语句,它会连续打印。所以有点不对劲,我想不出来。我
import 'package:flutter/material.dart';
import 'package:getx_hive_demo_one/presentation/event_list_screen/add_event_button.dart';
import 'package:get/get.dart';
import 'package:getx_hive_demo_one/database/database.dart';
import 'package:getx_hive_demo_one/models/event.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
class EventListScreen extends StatelessWidget {
final Database database = Get.put(Database());
GridSource dataSource;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Event Dashboard'),
backgroundColor: Colors.grey[850],
actions: [AddEventButton(source: dataSource)],
),
body: SafeArea(child: GetBuilder<Database>(
builder: (database) {
dataSource = GridSource(database.getEventList());
return SfDataGrid(
source: dataSource,
columnWidthMode: ColumnWidthMode.fill,
columns: <GridColumn>[
GridTextColumn(
columnName: 'name',
label: Container(
color: Colors.grey[800],
padding: EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: Text(
'Event',
style: TextStyle(color: Colors.white),
))),
GridTextColumn(
columnName: 'start',
label: Container(
color: Colors.grey[800],
padding: EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: Text(
'Start Date',
style: TextStyle(color: Colors.white),
))),
GridTextColumn(
columnName: 'duration',
label: Container(
color: Colors.grey[800],
padding: EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: Text(
'Event Duration',
style: TextStyle(color: Colors.white),
overflow: TextOverflow.ellipsis,
))),
GridTextColumn(
columnName: 'invitees',
label: Container(
color: Colors.grey[800],
padding: EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: Text(
'Attendees',
style: TextStyle(color: Colors.white),
))),
GridTextColumn(
columnName: 'location',
label: Container(
color: Colors.grey[800],
padding: EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: Text(
'Location',
style: TextStyle(color: Colors.white),
))),
],
);
},
)));
}
}
class GridSource extends DataGridSource {
List<DataGridRow> _eventGridRow = [];
List<Event> eventGrid = [];
GridSource(this.eventGrid) {
print('Run');
buildDataGridRows();
}
void buildDataGridRows() {
_eventGridRow = eventGrid
.map<DataGridRow>(
(event) => DataGridRow(
cells: [
DataGridCell<String>(columnName: 'name', value: event.eventName),
DataGridCell<String>(columnName: 'start', value: event.eventStart.toString()),
DataGridCell<String>(columnName: 'duration', value: event.eventDuration.toString()),
DataGridCell<String>(columnName: 'invitees', value: event.numberInvitees.toString()),
DataGridCell<String>(columnName: 'location', value: event.location),
],
),
)
.toList();
}
@override
List<DataGridRow> get rows => _eventGridRow;
@override
DataGridRowAdapter buildRow(DataGridRow row) {
final int index = _eventGridRow.indexOf(row);
Color getRowBackgroundColor() {
if (index % 2 == 0) {
return Colors.grey[100];
}
return Colors.transparent;
}
return DataGridRowAdapter(
color: getRowBackgroundColor(),
cells: [
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.all(8.0),
child: Text(
row.getCells()[0].value ?? '',
overflow: TextOverflow.ellipsis,
),
),
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.all(8.0),
child: Text(
row.getCells()[1].value ?? '',
overflow: TextOverflow.ellipsis,
),
),
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.all(8.0),
child: Text(
row.getCells()[2].value ?? '',
overflow: TextOverflow.ellipsis,
),
),
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.all(8.0),
child: Text(
row.getCells()[3].value ?? ' ',
overflow: TextOverflow.ellipsis,
),
),
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.all(8.0),
child: Text(
row.getCells()[4].value ?? '',
overflow: TextOverflow.ellipsis,
),
),
],
);
}
void updateDataGridSource() {
notifyListeners();
}
}
问题的原因是每次都创建GridSource,而且在buildDataRow中,您也在调用getEventList并刷新它,所以它会循环。请用下面提供的代码片段替换数据库和DataGrid 数据库
import 'package:flutter/foundation.dart';
///
///
/// HIVE DATABASE MODEL USING ENCRYPTION AND CRUD ACTIONS
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:getx_hive_demo_one/models/event.dart';
import 'package:get/get.dart';
import 'package:hive/hive.dart';
import 'dart:convert';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
import 'package:flutter/material.dart';
class Database extends GetxController {
GridSource dataGridSource;
Database() {
dataGridSource = GridSource(this);
}
// Hive box name
String _boxName = 'database';
// Initialize our list of contacts
List<Event> eventList = [];
// Holds our active contact
Event _activeEvent;
///
///
/// Encrypted Box
/// Create & open encrypted box
/// Return encrypted box for other methods to have box
Future<Box<Event>> encryptedBox() async {
final FlutterSecureStorage secureStorage = const FlutterSecureStorage();
var containsEncryptionKey = await secureStorage.containsKey(key: 'key');
if (!containsEncryptionKey) {
var key = Hive.generateSecureKey();
await secureStorage.write(key: 'key', value: base64UrlEncode(key));
}
var encryptionKey = base64Url.decode(await secureStorage.read(key: 'key'));
var box = await Hive.openBox<Event>(_boxName,
encryptionCipher: HiveAesCipher(encryptionKey));
return box;
}
///
///
/// Create Event
/// Saves data to hive box, updates repository & notify listeners
void addEvent(Event newEvent) async {
var box = await Hive.openBox<Event>(_boxName);
await box.add(newEvent);
eventList = box.values.toList();
refresh();
}
///
///
/// Read Event
/// Sends events in database to list repository
void getEvents() async {
var box = await Hive.openBox<Event>(_boxName);
eventList = box.values.toList();
refresh();
}
///
///
/// Read Event
/// Returns event list
List<Event> getEventList() {
getEvents();
return eventList;
}
///
///
/// Read Event
/// Gets contact by index from repository
Event getEvent(index) {
return eventList[index];
}
///
///
/// Read Event
/// Gets length of event repository
int get eventCount {
return eventList.length;
}
///
///
/// Read Event
/// Sets active event to notify listeners for
void setActiveEvent(key) async {
var box = await Hive.openBox<Event>(_boxName);
_activeEvent = box.get(key);
refresh();
}
///
///
/// Read Event
/// Get active event
Event getActiveEvent() {
return _activeEvent;
}
///
///
/// Update Event
/// Updates event info with new data
void editEvent({Event event, int eventKey}) async {
var box = await Hive.openBox<Event>(_boxName);
await box.put(eventKey, event);
eventList = box.values.toList();
_activeEvent = box.get(eventKey);
refresh();
}
void deleteAll() async{
var box = await Hive.openBox<Event>(_boxName);
box.deleteFromDisk();
refresh();
}
///
///
/// Delete Event
/// Deletes event from box and updates list
void deleteEvent(key) async {
var box = await Hive.openBox<Event>(_boxName);
await box.delete(key);
eventList = box.values.toList();
print('Deleted event at:' + key.toString());
refresh();
}
/// Non-encrypted box
/// var box = await Hive.openBox<Event>(_boxName);
}
class GridSource extends DataGridSource {
List<DataGridRow> _eventGridRow = [];
final Database database;
List eventList = [];
GridSource(this.database) {
this.database.addListener(handleListChanges);
}
void handleListChanges() {
if (!listEquals(eventList, this.database.eventList)) {
eventList = this.database.eventList;
buildDataGridRows();
notifyListeners();
}
}
void buildDataGridRows() {
_eventGridRow = eventList
.map<DataGridRow>(
(event) => DataGridRow(
cells: [
DataGridCell<String>(columnName: 'name', value: event.eventName),
DataGridCell<String>(
columnName: 'start', value: event.eventStart.toString()),
DataGridCell<String>(
columnName: 'duration',
value: event.eventDuration.toString()),
DataGridCell<String>(
columnName: 'invitees',
value: event.numberInvitees.toString()),
DataGridCell<String>(
columnName: 'location', value: event.location),
],
),
)
.toList();
}
@override
List<DataGridRow> get rows => _eventGridRow;
@override
DataGridRowAdapter buildRow(DataGridRow row) {
final int index = _eventGridRow.indexOf(row);
Color getRowBackgroundColor() {
if (index % 2 == 0) {
return Colors.grey[100];
}
return Colors.transparent;
}
return DataGridRowAdapter(
color: getRowBackgroundColor(),
cells: [
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.all(8.0),
child: Text(
row.getCells()[0].value,
overflow: TextOverflow.ellipsis,
),
),
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.all(8.0),
child: Text(
row.getCells()[1].value,
overflow: TextOverflow.ellipsis,
),
),
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.all(8.0),
child: Text(
row.getCells()[2].value,
overflow: TextOverflow.ellipsis,
),
),
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.all(8.0),
child: Text(
row.getCells()[3].value,
overflow: TextOverflow.ellipsis,
),
),
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.all(8.0),
child: Text(
row.getCells()[4].value,
overflow: TextOverflow.ellipsis,
),
),
],
);
}
}
导入“包:flift/foundation.dart”;
///
///
///使用加密和CRUD操作的配置单元数据库模型
进口“包装:颤振安全存储/颤振安全存储.dart”;
导入“package:getx_hive_demo_one/models/event.dart”;
导入“package:get/get.dart”;
导入“package:hive/hive.dart”;
导入“dart:convert”;
导入“包:syncfusion_flatter_datagrid/datagrid.dart”;
进口“包装:颤振/材料.省道”;
类数据库扩展了GetxController{
GridSource数据源GridSource;
数据库(){
dataGridSource=GridSource(此);
}
//蜂箱名称
字符串_boxName='数据库';
//初始化我们的联系人列表
列表事件列表=[];
//保持我们的积极联系
事件_activeEvent;
///
///
///加密盒
///创建并打开加密框
///返回加密框,以使其他方法具有加密框
Future encryptedBox()异步{
最终颤振安全存储安全存储=常数颤振安全存储();
var containsEncryptionKey=wait secureStorage.containsKey(key:'key');
如果(!containsEncryptionKey){
var key=Hive.generateSecureKey();
等待secureStorage.write(key:'key',value:base64UrlEncode(key));
}
var encryptionKey=base64Url.decode(等待secureStorage.read(key:'key'));
var-box=等待配置单元.openBox(_-boxName,
encryptionCipher:HiveaeSpipher(encryptionKey));
返回框;
}
///
///
///创建事件
///将数据保存到配置单元框、更新存储库和通知侦听器
void addEvent(Event newEvent)异步{
var-box=wait-Hive.openBox(_-boxName);
等待框。添加(newEvent);
eventList=box.values.toList();
刷新();
}
///
///
///读取事件
///将数据库中的事件发送到列表存储库
void getEvents()异步{
var-box=wait-Hive.openBox(_-boxName);
eventList=box.values.toList();
刷新();
}
///
///
///读取事件
///返回事件列表
列表getEventList(){
getEvents();
返回事件列表;
}
///
///
///读取事件
///从存储库中按索引获取联系人
事件获取事件(索引){
返回事件列表[索引];
}
///
///
///读取事件
///获取事件存储库的长度
int获取事件计数{
返回eventList.length;
}
///
///
///读取事件
///设置要通知侦听器的活动事件
void setActiveEvent(键)异步{
var-box=wait-Hive.openBox(_-boxName);
_activeEvent=box.get(key);
刷新();
}
///
///
///读取事件
///获取活动事件
事件getActiveEvent(){
返回活动事件;
}
///
///
///更新事件
///使用新数据更新事件信息
void editEvent({Event Event,int eventKey})异步{
var-box=wait-Hive.openBox(_-boxName);
等待框。放置(事件键,事件);
eventList=box.values.toList();
_activeEvent=box.get(eventKey);
刷新();
}
void deleteAll()异步{
var-box=wait-Hive.openBox(_-boxName);
box.deleteFromDisk();
刷新();
}
///
///
///删除事件
///从框中删除事件并更新列表
void deleteEvent(键)异步{
var-box=wait-Hive.openBox(_-boxName);
等待框。删除(键);
eventList=box.values.toList();
打印('Deleted event at:'+key.toString());
刷新();
}
///非加密盒
///var-box=wait-Hive.openBox(_-boxName);
}
类GridSource扩展了DataGridSource{
列表_eventGridRow=[];
最终数据库;
列表事件列表=[];
GridSource(this.database){
this.database.addListener(handleListChanges);
}
void handleListChanges(){
if(!listQuals(eventList,this.database.eventList)){
eventList=this.database.eventList;
buildDataGridRows();
notifyListeners();
}
}
void buildDataGridRows(){
_eventGridRow=eventList
.地图(
(事件)=>DataGridRow(
单元格:[
DataGridCell(columnName:'name',值:event.eventName),
数据网格单元(
columnName:'start',值:event.eventStart.toString()),
数据网格单元(
columnName:'持续时间',
值:event.eventDuration.toString()),
数据网格单元(
columnName:“被邀请者”,
值:event.numberInvitees.toString()),
数据网格单元(
columnName:“位置”,值:event.location),
],
),
)
.toList();
}
@凌驾
List get rows=>\u eventGridRow;
@凌驾
DataGridRow适配器构建行(DataGridRow行){
最终整数索引=_eventGridRow.indexOf(row);
颜色getRowBackgroundColor(){
如果(索引%2==0){
返回颜色
import 'package:flutter/foundation.dart';
///
///
/// HIVE DATABASE MODEL USING ENCRYPTION AND CRUD ACTIONS
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:getx_hive_demo_one/models/event.dart';
import 'package:get/get.dart';
import 'package:hive/hive.dart';
import 'dart:convert';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
import 'package:flutter/material.dart';
class Database extends GetxController {
GridSource dataGridSource;
Database() {
dataGridSource = GridSource(this);
}
// Hive box name
String _boxName = 'database';
// Initialize our list of contacts
List<Event> eventList = [];
// Holds our active contact
Event _activeEvent;
///
///
/// Encrypted Box
/// Create & open encrypted box
/// Return encrypted box for other methods to have box
Future<Box<Event>> encryptedBox() async {
final FlutterSecureStorage secureStorage = const FlutterSecureStorage();
var containsEncryptionKey = await secureStorage.containsKey(key: 'key');
if (!containsEncryptionKey) {
var key = Hive.generateSecureKey();
await secureStorage.write(key: 'key', value: base64UrlEncode(key));
}
var encryptionKey = base64Url.decode(await secureStorage.read(key: 'key'));
var box = await Hive.openBox<Event>(_boxName,
encryptionCipher: HiveAesCipher(encryptionKey));
return box;
}
///
///
/// Create Event
/// Saves data to hive box, updates repository & notify listeners
void addEvent(Event newEvent) async {
var box = await Hive.openBox<Event>(_boxName);
await box.add(newEvent);
eventList = box.values.toList();
refresh();
}
///
///
/// Read Event
/// Sends events in database to list repository
void getEvents() async {
var box = await Hive.openBox<Event>(_boxName);
eventList = box.values.toList();
refresh();
}
///
///
/// Read Event
/// Returns event list
List<Event> getEventList() {
getEvents();
return eventList;
}
///
///
/// Read Event
/// Gets contact by index from repository
Event getEvent(index) {
return eventList[index];
}
///
///
/// Read Event
/// Gets length of event repository
int get eventCount {
return eventList.length;
}
///
///
/// Read Event
/// Sets active event to notify listeners for
void setActiveEvent(key) async {
var box = await Hive.openBox<Event>(_boxName);
_activeEvent = box.get(key);
refresh();
}
///
///
/// Read Event
/// Get active event
Event getActiveEvent() {
return _activeEvent;
}
///
///
/// Update Event
/// Updates event info with new data
void editEvent({Event event, int eventKey}) async {
var box = await Hive.openBox<Event>(_boxName);
await box.put(eventKey, event);
eventList = box.values.toList();
_activeEvent = box.get(eventKey);
refresh();
}
void deleteAll() async{
var box = await Hive.openBox<Event>(_boxName);
box.deleteFromDisk();
refresh();
}
///
///
/// Delete Event
/// Deletes event from box and updates list
void deleteEvent(key) async {
var box = await Hive.openBox<Event>(_boxName);
await box.delete(key);
eventList = box.values.toList();
print('Deleted event at:' + key.toString());
refresh();
}
/// Non-encrypted box
/// var box = await Hive.openBox<Event>(_boxName);
}
class GridSource extends DataGridSource {
List<DataGridRow> _eventGridRow = [];
final Database database;
List eventList = [];
GridSource(this.database) {
this.database.addListener(handleListChanges);
}
void handleListChanges() {
if (!listEquals(eventList, this.database.eventList)) {
eventList = this.database.eventList;
buildDataGridRows();
notifyListeners();
}
}
void buildDataGridRows() {
_eventGridRow = eventList
.map<DataGridRow>(
(event) => DataGridRow(
cells: [
DataGridCell<String>(columnName: 'name', value: event.eventName),
DataGridCell<String>(
columnName: 'start', value: event.eventStart.toString()),
DataGridCell<String>(
columnName: 'duration',
value: event.eventDuration.toString()),
DataGridCell<String>(
columnName: 'invitees',
value: event.numberInvitees.toString()),
DataGridCell<String>(
columnName: 'location', value: event.location),
],
),
)
.toList();
}
@override
List<DataGridRow> get rows => _eventGridRow;
@override
DataGridRowAdapter buildRow(DataGridRow row) {
final int index = _eventGridRow.indexOf(row);
Color getRowBackgroundColor() {
if (index % 2 == 0) {
return Colors.grey[100];
}
return Colors.transparent;
}
return DataGridRowAdapter(
color: getRowBackgroundColor(),
cells: [
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.all(8.0),
child: Text(
row.getCells()[0].value,
overflow: TextOverflow.ellipsis,
),
),
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.all(8.0),
child: Text(
row.getCells()[1].value,
overflow: TextOverflow.ellipsis,
),
),
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.all(8.0),
child: Text(
row.getCells()[2].value,
overflow: TextOverflow.ellipsis,
),
),
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.all(8.0),
child: Text(
row.getCells()[3].value,
overflow: TextOverflow.ellipsis,
),
),
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.all(8.0),
child: Text(
row.getCells()[4].value,
overflow: TextOverflow.ellipsis,
),
),
],
);
}
}
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:getx_hive_demo_one/database/database.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
class DataGrid extends StatelessWidget {
final Database database = Get.put(Database());
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: GetBuilder<Database>(
builder: (database) {
return SfDataGrid(
source: database.dataGridSource,
columnWidthMode: ColumnWidthMode.fill,
columns: <GridColumn>[
GridTextColumn(
columnName: 'name',
label: Container(
color: Colors.grey[800],
padding: EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: Text(
'Event',
style: TextStyle(color: Colors.white),
))),
GridTextColumn(
columnName: 'start',
label: Container(
color: Colors.grey[800],
padding: EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: Text(
'Start Date',
style: TextStyle(color: Colors.white),
))),
GridTextColumn(
columnName: 'duration',
label: Container(
color: Colors.grey[800],
padding: EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: Text(
'Event Duration',
style: TextStyle(color: Colors.white),
overflow: TextOverflow.ellipsis,
))),
GridTextColumn(
columnName: 'invitees',
label: Container(
color: Colors.grey[800],
padding: EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: Text(
'Attendees',
style: TextStyle(color: Colors.white),
))),
GridTextColumn(
columnName: 'location',
label: Container(
color: Colors.grey[800],
padding: EdgeInsets.all(8.0),
alignment: Alignment.centerLeft,
child: Text(
'Location',
style: TextStyle(color: Colors.white),
))),
],
);
})),
);
}
}