feat(perf): offload Android SMS parsing to Isolate and wrap pie chart with RepaintBoundary
This commit is contained in:
@@ -10,6 +10,7 @@ import '../themed_text.dart';
|
||||
import 'analysis_badge.dart';
|
||||
import '../../l10n/app_localizations.dart';
|
||||
import '../../providers/locale_provider.dart';
|
||||
import '../../utils/reduce_motion.dart';
|
||||
|
||||
/// 구독 서비스 비율을 파이 차트로 보여주는 카드 위젯
|
||||
class SubscriptionPieChartCard extends StatefulWidget {
|
||||
@@ -312,58 +313,69 @@ class _SubscriptionPieChartCardState extends State<SubscriptionPieChartCard> {
|
||||
);
|
||||
}
|
||||
|
||||
return PieChart(
|
||||
PieChartData(
|
||||
borderData: FlBorderData(show: false),
|
||||
sectionsSpace: 2,
|
||||
centerSpaceRadius: 60,
|
||||
sections:
|
||||
_applyTouchedState(snapshot.data!),
|
||||
pieTouchData: PieTouchData(
|
||||
enabled: true,
|
||||
touchCallback: (FlTouchEvent event,
|
||||
pieTouchResponse) {
|
||||
// 터치 응답이 없거나 섹션이 없는 경우
|
||||
if (pieTouchResponse == null ||
|
||||
pieTouchResponse.touchedSection ==
|
||||
null) {
|
||||
// 차트 밖으로 나갔을 때만 리셋
|
||||
if (_touchedIndex != -1) {
|
||||
setState(() {
|
||||
_touchedIndex = -1;
|
||||
});
|
||||
return RepaintBoundary(
|
||||
child: PieChart(
|
||||
PieChartData(
|
||||
borderData: FlBorderData(show: false),
|
||||
sectionsSpace: 2,
|
||||
centerSpaceRadius: 60,
|
||||
sections:
|
||||
_applyTouchedState(snapshot.data!),
|
||||
pieTouchData: PieTouchData(
|
||||
enabled: true,
|
||||
touchCallback: (FlTouchEvent event,
|
||||
pieTouchResponse) {
|
||||
// 터치 응답이 없거나 섹션이 없는 경우
|
||||
if (pieTouchResponse == null ||
|
||||
pieTouchResponse
|
||||
.touchedSection ==
|
||||
null) {
|
||||
// 차트 밖으로 나갔을 때만 리셋
|
||||
if (_touchedIndex != -1) {
|
||||
setState(() {
|
||||
_touchedIndex = -1;
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final touchedIndex = pieTouchResponse
|
||||
.touchedSection!
|
||||
.touchedSectionIndex;
|
||||
final touchedIndex =
|
||||
pieTouchResponse.touchedSection!
|
||||
.touchedSectionIndex;
|
||||
|
||||
// 탭 이벤트 처리 (토글)
|
||||
if (event is FlTapUpEvent) {
|
||||
setState(() {
|
||||
// 동일 섹션 탭하면 선택 해제, 아니면 선택
|
||||
_touchedIndex = (_touchedIndex ==
|
||||
touchedIndex)
|
||||
? -1
|
||||
: touchedIndex;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// hover 이벤트 처리 (단순 표시)
|
||||
if (event is FlPointerHoverEvent ||
|
||||
event is FlPointerEnterEvent) {
|
||||
// 현재 인덱스와 다른 경우만 업데이트
|
||||
if (_touchedIndex != touchedIndex) {
|
||||
// 탭 이벤트 처리 (토글)
|
||||
if (event is FlTapUpEvent) {
|
||||
setState(() {
|
||||
_touchedIndex = touchedIndex;
|
||||
// 동일 섹션 탭하면 선택 해제, 아니면 선택
|
||||
_touchedIndex =
|
||||
(_touchedIndex ==
|
||||
touchedIndex)
|
||||
? -1
|
||||
: touchedIndex;
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// hover 이벤트 처리 (단순 표시)
|
||||
if (event is FlPointerHoverEvent ||
|
||||
event is FlPointerEnterEvent) {
|
||||
// 현재 인덱스와 다른 경우만 업데이트
|
||||
if (_touchedIndex !=
|
||||
touchedIndex) {
|
||||
setState(() {
|
||||
_touchedIndex = touchedIndex;
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
swapAnimationDuration:
|
||||
ReduceMotion.isEnabled(context)
|
||||
? const Duration(milliseconds: 0)
|
||||
: const Duration(
|
||||
milliseconds: 300),
|
||||
swapAnimationCurve: Curves.easeOut,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user