FIX keyboard
This commit is contained in:
127
lib/main.dart
127
lib/main.dart
@@ -307,17 +307,20 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
return _formatDuration(duration);
|
||||
}
|
||||
|
||||
// Update keyboard handler method to use modern KeyEvent API
|
||||
void _handleKeyEvent(KeyEvent event) {
|
||||
// Only process key down events to avoid duplicate triggers
|
||||
if (event is KeyDownEvent) {
|
||||
// Handle Space key
|
||||
if (event.logicalKey == LogicalKeyboardKey.space) {
|
||||
// Space: Start if paused, Lap if running
|
||||
if (_isRunning) {
|
||||
_recordLap();
|
||||
} else {
|
||||
_startTimer();
|
||||
}
|
||||
} else if (event.logicalKey == LogicalKeyboardKey.enter) {
|
||||
// Enter: Stop if paused, Pause if running
|
||||
}
|
||||
// Handle Enter key
|
||||
else if (event.logicalKey == LogicalKeyboardKey.enter) {
|
||||
if (_isRunning) {
|
||||
_pauseTimer();
|
||||
} else {
|
||||
@@ -336,74 +339,84 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return KeyboardListener(
|
||||
// Use Focus directly to capture key events
|
||||
return Focus(
|
||||
focusNode: _focusNode,
|
||||
onKeyEvent: _handleKeyEvent,
|
||||
autofocus: true,
|
||||
onKeyEvent: (FocusNode node, KeyEvent event) {
|
||||
_handleKeyEvent(event);
|
||||
// Always return KeyEventResult.handled to indicate we've processed the event
|
||||
return KeyEventResult.handled;
|
||||
},
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||
title: Text(widget.title),
|
||||
),
|
||||
body: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const SizedBox(height: 10),
|
||||
// Use a fixed height container to prevent expanding and force horizontal scrolling if needed
|
||||
SizedBox(
|
||||
height: 50,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Text(
|
||||
_formatDuration(_elapsedTime),
|
||||
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
|
||||
fontFamily: 'monospace', // Use monospaced font for fixed-width characters
|
||||
body: GestureDetector(
|
||||
// This ensures tapping anywhere gives focus back to our listener
|
||||
onTap: () => _focusNode.requestFocus(),
|
||||
behavior: HitTestBehavior.translucent,
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const SizedBox(height: 10),
|
||||
// Use a fixed height container to prevent expanding and force horizontal scrolling if needed
|
||||
SizedBox(
|
||||
height: 50,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Text(
|
||||
_formatDuration(_elapsedTime),
|
||||
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
|
||||
fontFamily: 'monospace', // Use monospaced font for fixed-width characters
|
||||
),
|
||||
softWrap: false, // Prevent text wrapping
|
||||
overflow: TextOverflow.visible, // Allow text to extend beyond bounds
|
||||
),
|
||||
softWrap: false, // Prevent text wrapping
|
||||
overflow: TextOverflow.visible, // Allow text to extend beyond bounds
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 30),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: _isRunning ? _pauseTimer : _startTimer,
|
||||
child: Text(_isRunning ? 'Pause' : 'Start'),
|
||||
const SizedBox(height: 30),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: _isRunning ? _pauseTimer : _startTimer,
|
||||
child: Text(_isRunning ? 'Pause' : 'Start'),
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
ElevatedButton(
|
||||
onPressed: _stopTimer,
|
||||
child: const Text('Stop'),
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
ElevatedButton(
|
||||
onPressed: _recordLap,
|
||||
child: const Text('Lap'),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
if (_laps.isNotEmpty) ...[
|
||||
Text(
|
||||
'Laps:',
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
ElevatedButton(
|
||||
onPressed: _stopTimer,
|
||||
child: const Text('Stop'),
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
ElevatedButton(
|
||||
onPressed: _recordLap,
|
||||
child: const Text('Lap'),
|
||||
const SizedBox(height: 10),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: _laps.length,
|
||||
itemBuilder: (context, index) {
|
||||
return ListTile(
|
||||
title: Text('Lap ${index + 1}: ${_laps[index]}'),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
if (_laps.isNotEmpty) ...[
|
||||
Text(
|
||||
'Laps:',
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: _laps.length,
|
||||
itemBuilder: (context, index) {
|
||||
return ListTile(
|
||||
title: Text('Lap ${index + 1}: ${_laps[index]}'),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
Reference in New Issue
Block a user