yx_tracking_flutter/example/lib/main.dart

192 lines
4.9 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:yx_tracking_flutter/yx_tracking_flutter.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Analytics.init(
const AnalyticsConfig(
systemCode: 'DEMO_APP',
endpointBaseUrl: 'https://example.com/api/ExternalEventlogs',
clientType: 3,
enableDebug: true,
batchSize: 5,
flushInterval: 30,
),
);
runApp(const DemoApp());
}
class DemoApp extends StatelessWidget {
const DemoApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: DemoPage(),
);
}
}
class DemoPage extends StatefulWidget {
const DemoPage({super.key});
@override
State<DemoPage> createState() => _DemoPageState();
}
class _DemoPageState extends State<DemoPage> {
int _cacheCount = 0;
List<RecentEventSummary> _recent = const <RecentEventSummary>[];
bool _flushing = false;
bool _refreshingConfig = false;
Timer? _pollTimer;
@override
void initState() {
super.initState();
_refreshCount();
_pollTimer = Timer.periodic(const Duration(seconds: 2), (_) {
_refreshCount();
});
}
@override
void dispose() {
_pollTimer?.cancel();
super.dispose();
}
Future<void> _refreshCount() async {
final results = await Future.wait(<Future<Object>>[
Analytics.cachedEventCount(),
Analytics.cachedRecentEvents(limit: 20),
]);
final count = results[0] as int;
final recent = results[1] as List<RecentEventSummary>;
if (!mounted) {
return;
}
setState(() {
_cacheCount = count;
_recent = recent;
});
}
Future<void> _trackDemoEvent() async {
await Analytics.track(
'DEMO_BUTTON_CLICK',
eventParams: const <String, dynamic>{'page': 'demo'},
customTags: const <String, dynamic>{
'tenantId': 't1',
'feature': 'demo',
},
);
await _refreshCount();
}
Future<void> _flushNow() async {
if (_flushing) {
return;
}
setState(() {
_flushing = true;
});
try {
await Analytics.flush(force: true);
} finally {
if (mounted) {
setState(() {
_flushing = false;
});
}
await _refreshCount();
}
}
Future<void> _refreshConfig() async {
if (_refreshingConfig) {
return;
}
setState(() {
_refreshingConfig = true;
});
try {
await Analytics.refreshConfig(force: true);
} finally {
if (mounted) {
setState(() {
_refreshingConfig = false;
});
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('YX Tracking Demo')),
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'本地缓存事件数:$_cacheCount',
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 16),
Wrap(
spacing: 12,
runSpacing: 12,
children: <Widget>[
ElevatedButton(
onPressed: _trackDemoEvent,
child: const Text('Track Demo Event'),
),
ElevatedButton(
onPressed: _flushing ? null : _flushNow,
child: Text(_flushing ? 'Flushing...' : 'Flush Now'),
),
OutlinedButton(
onPressed: _refreshingConfig ? null : _refreshConfig,
child: Text(_refreshingConfig ? 'Refreshing...' : 'Refresh Config'),
),
],
),
const SizedBox(height: 12),
const Text(
'说明Demo 使用 example.com 作为占位地址,'
'实际联调时请替换为真实 HTTPS 域名。',
),
const SizedBox(height: 12),
Text('最近事件(最多 20 条)', style: Theme.of(context).textTheme.titleSmall),
const SizedBox(height: 8),
Expanded(
child: _recent.isEmpty
? const Text('暂无事件')
: ListView.separated(
itemCount: _recent.length,
separatorBuilder: (_, __) => const Divider(height: 1),
itemBuilder: (context, index) {
final item = _recent[index];
return ListTile(
dense: true,
title: Text(item.eventType),
subtitle: Text(
'${item.createTime.toIso8601String()} · retry=${item.retryCount}',
),
);
},
),
),
],
),
),
);
}
}