fix: solve the problem that errors may occur during merging

This commit is contained in:
Nedifinita
2025-10-14 23:55:42 +08:00
parent 5533df92b5
commit 6073ea615e
3 changed files with 81 additions and 84 deletions

View File

@@ -221,28 +221,43 @@ class HistoryScreenState extends State<HistoryScreen> {
if (mounted) {
if (_isAtTop) {
setState(() {
bool isMerge = false;
Object? mergeResult;
if (_displayItems.isNotEmpty) {
final firstItem = _displayItems.first;
List<TrainRecord> tempRecords = [newRecord];
if (firstItem is MergedTrainRecord) {
tempRecords.addAll(firstItem.records);
} else if (firstItem is TrainRecord) {
tempRecords.add(firstItem);
}
final mergeCheckResult =
MergeService.getMixedList(tempRecords, _mergeSettings);
if (mergeCheckResult.length == 1 &&
mergeCheckResult.first is MergedTrainRecord) {
isMerge = true;
mergeResult = mergeCheckResult.first;
List<TrainRecord> allRecords = [];
Set<String> selectedRecordIds = {};
for (final item in _displayItems) {
if (item is MergedTrainRecord) {
allRecords.addAll(item.records);
if (_selectedRecords.contains(item.records.first.uniqueId)) {
selectedRecordIds.addAll(item.records.map((r) => r.uniqueId));
}
} else if (item is TrainRecord) {
allRecords.add(item);
if (_selectedRecords.contains(item.uniqueId)) {
selectedRecordIds.add(item.uniqueId);
}
}
}
if (isMerge) {
_displayItems[0] = mergeResult!;
} else {
_displayItems.insert(0, newRecord);
allRecords.insert(0, newRecord);
final mergedItems =
MergeService.getMixedList(allRecords, _mergeSettings);
_displayItems.clear();
_displayItems.addAll(mergedItems);
_selectedRecords.clear();
for (final item in _displayItems) {
if (item is MergedTrainRecord) {
if (item.records
.any((r) => selectedRecordIds.contains(r.uniqueId))) {
_selectedRecords.addAll(item.records.map((r) => r.uniqueId));
}
} else if (item is TrainRecord) {
if (selectedRecordIds.contains(item.uniqueId)) {
_selectedRecords.add(item.uniqueId);
}
}
}
});
if (_scrollController.hasClients) {
@@ -723,8 +738,6 @@ class HistoryScreenState extends State<HistoryScreen> {
Widget _buildRecordCard(TrainRecord record,
{bool isSubCard = false, Key? key}) {
final isSelected = _selectedRecords.contains(record.uniqueId);
final isExpanded =
!isSubCard && (_expandedStates[record.uniqueId] ?? false);
return Card(
key: key,
@@ -752,6 +765,11 @@ class HistoryScreenState extends State<HistoryScreen> {
}
widget.onSelectionChanged();
});
} else {
setState(() {
_expandedStates[record.uniqueId] =
!(_expandedStates[record.uniqueId] ?? false);
});
}
},
onLongPress: () {
@@ -771,7 +789,8 @@ class HistoryScreenState extends State<HistoryScreen> {
_buildRecordHeader(record),
_buildPositionAndSpeed(record),
_buildLocoInfo(record),
if (isExpanded) _buildExpandedContent(record),
if (_expandedStates[record.uniqueId] ?? false)
_buildExpandedContent(record),
]))));
}
@@ -803,6 +822,7 @@ class HistoryScreenState extends State<HistoryScreen> {
final hasLocoInfo =
formattedLocoInfo.isNotEmpty && formattedLocoInfo != "<NUL>";
final shouldShowTrainRow = hasTrainNumber || hasDirection || hasLocoInfo;
final hasPosition = _parsePosition(record.positionInfo) != null;
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [
@@ -856,7 +876,8 @@ class HistoryScreenState extends State<HistoryScreen> {
])),
if (hasLocoInfo)
Text(formattedLocoInfo,
style: const TextStyle(fontSize: 14, color: Colors.white70))
style:
const TextStyle(fontSize: 14, color: Colors.white70)),
]),
const SizedBox(height: 2)
]

View File

@@ -142,7 +142,6 @@ class RealtimeScreenState extends State<RealtimeScreen> {
}
} catch (e) {
_selectedGroupKeys.remove(groupKey);
print('记录不存在,移除选中状态: $groupKey');
}
}
@@ -227,7 +226,6 @@ class RealtimeScreenState extends State<RealtimeScreen> {
}
} catch (e) {
_selectedGroupKeys.remove(groupKey);
print('记录不存在,移除选中状态: $groupKey');
}
}
@@ -275,7 +273,6 @@ class RealtimeScreenState extends State<RealtimeScreen> {
}
} catch (e) {
_selectedGroupKeys.remove(groupKey);
print('记录不存在,移除选中状态: $groupKey');
}
}
@@ -460,25 +457,19 @@ class RealtimeScreenState extends State<RealtimeScreen> {
void initState() {
super.initState();
_scrollController.addListener(() {
print(
'滚动监听器触发 - 当前位置: ${_scrollController.position.pixels}, maxScrollExtent: ${_scrollController.position.maxScrollExtent}, isAtTop: $_isAtTop');
if (_scrollController.position.atEdge) {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent) {
print('到达底部(反转后的"顶部"- 设置 _isAtTop = true');
if (!_isAtTop) {
setState(() => _isAtTop = true);
}
} else if (_scrollController.position.pixels == 0) {
print('到达顶部(反转后的"底部"- 设置 _isAtTop = false');
if (_isAtTop) {
setState(() => _isAtTop = false);
}
}
} else {
if (_isAtTop) {
print('离开底部(反转后的"顶部"- 设置 _isAtTop = false');
setState(() => _isAtTop = false);
}
}
@@ -501,16 +492,12 @@ class RealtimeScreenState extends State<RealtimeScreen> {
if (mounted && _scrollController.hasClients && _displayItems.isNotEmpty) {
try {
final maxScrollExtent = _scrollController.position.maxScrollExtent;
print('初始滚动执行maxScrollExtent=$maxScrollExtent');
_scrollController.jumpTo(maxScrollExtent);
print('初始滚动完成:位置=${_scrollController.position.pixels}');
if (!_isAtTop) {
setState(() => _isAtTop = true);
}
} catch (e) {
print('初始滚动错误:$e');
}
} catch (e) {}
}
});
}
@@ -675,13 +662,8 @@ class RealtimeScreenState extends State<RealtimeScreen> {
try {
final maxScrollExtent =
_scrollController.position.maxScrollExtent;
print('loadRecords - 滚动到底部, maxScrollExtent: $maxScrollExtent');
_scrollController.jumpTo(maxScrollExtent);
print(
'loadRecords - 滚动完成,新位置: ${_scrollController.position.pixels}');
} catch (e) {
print('loadRecords - 滚动错误: $e');
}
} catch (e) {}
}
} else {
if (_isLoading) {
@@ -697,11 +679,9 @@ class RealtimeScreenState extends State<RealtimeScreen> {
}
Future<void> addNewRecord(TrainRecord newRecord) async {
print('addNewRecord - 开始添加新记录, 当前_isAtTop=$_isAtTop');
try {
final position = _parsePositionFromRecord(newRecord);
if (position == null) {
print('addNewRecord - 记录没有位置信息,忽略');
return;
}
@@ -721,41 +701,44 @@ class RealtimeScreenState extends State<RealtimeScreen> {
if (!isNewRecord) return;
if (mounted) {
setState(() {
bool isMerge = false;
Object? mergeResult;
String? oldSingleRecordKey;
List<TrainRecord> allRecords = [];
Set<String> selectedRecordIds = {};
if (_displayItems.isNotEmpty) {
final firstItem = _displayItems.first;
List<TrainRecord> tempRecords = [newRecord];
if (firstItem is MergedTrainRecord) {
tempRecords.addAll(firstItem.records);
} else if (firstItem is TrainRecord) {
tempRecords.add(firstItem);
oldSingleRecordKey = "single:${firstItem.uniqueId}";
for (final item in _displayItems) {
if (item is MergedTrainRecord) {
allRecords.addAll(item.records);
if (_selectedGroupKeys.contains(item.groupKey)) {
selectedRecordIds.addAll(item.records.map((r) => r.uniqueId));
}
final mergeCheckResult =
MergeService.getMixedList(tempRecords, _mergeSettings);
if (mergeCheckResult.length == 1 &&
mergeCheckResult.first is MergedTrainRecord) {
isMerge = true;
mergeResult = mergeCheckResult.first;
} else if (item is TrainRecord) {
allRecords.add(item);
if (_selectedGroupKeys.contains("single:${item.uniqueId}")) {
selectedRecordIds.add(item.uniqueId);
}
}
}
if (isMerge) {
final mergedRecord = mergeResult as MergedTrainRecord;
_displayItems[0] = mergedRecord;
allRecords.insert(0, newRecord);
if (oldSingleRecordKey != null &&
_selectedGroupKeys.contains(oldSingleRecordKey)) {
_selectedGroupKeys.remove(oldSingleRecordKey);
_selectedGroupKeys.add(mergedRecord.groupKey);
final mergedItems =
MergeService.getMixedList(allRecords, _mergeSettings);
setState(() {
_displayItems.clear();
_displayItems.addAll(mergedItems);
_selectedGroupKeys.clear();
for (final item in _displayItems) {
if (item is MergedTrainRecord) {
if (item.records
.any((r) => selectedRecordIds.contains(r.uniqueId))) {
_selectedGroupKeys.add(item.groupKey);
}
} else if (item is TrainRecord) {
if (selectedRecordIds.contains(item.uniqueId)) {
_selectedGroupKeys.add("single:${item.uniqueId}");
}
}
} else {
_displayItems.insert(0, newRecord);
}
});
@@ -765,23 +748,16 @@ class RealtimeScreenState extends State<RealtimeScreen> {
_adjustMapViewToSelectedGroups();
}
print(
'addNewRecord - 检查滚动条件: _isAtTop=$_isAtTop, hasClients=${_scrollController.hasClients}, 当前位置: ${_scrollController.position.pixels}');
if (_isAtTop && _scrollController.hasClients) {
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted && _scrollController.hasClients) {
final newMaxScrollExtent =
_scrollController.position.maxScrollExtent;
print(
'addNewRecord - 执行滚动到底部, maxScrollExtent: $newMaxScrollExtent');
_scrollController.jumpTo(newMaxScrollExtent);
print(
'addNewRecord - 滚动完成,新位置: ${_scrollController.position.pixels}');
}
});
} else {
print('addNewRecord - 不执行滚动,条件不满足');
}
} else {}
}
} catch (e) {}
}