greenrat
@greenrat

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

【Flutter】 日本語入力がONの状態でキーイベントを取得したい

解決したいこと

Flutterでデスクトップアプリをつくっています。
テキストフィールドへの入力中に特定のキーが押されたことを検出して所定の動作をさせたいのですが上手くいきません。
また、もしFlutterでは実現不可能な場合、実現可能なデスクトップアプリ用のフレームワークを教えてください。軽快でモダンUIを簡単に作れるものが嬉しいです。

発生している問題・エラー

@キーを押したら "hoge" と入力するようにしたいのですが、日本語入力モードでは単に全角の @ が入力されます。
日本語入力モードがOFFのときは予定通り "hoge" と入力できます。

該当するソースコード

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  var _controller = TextEditingController();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              '@key を押すと hoge と入力される。',
            ),
            Focus(
              autofocus: true,
              onKeyEvent: (node, event) {
                if (event is KeyDownEvent) {
                  if (event.logicalKey == LogicalKeyboardKey.backquote) { // なぜか .at ではなく .backquote で検出。
                    const hoge = 'hoge';
                    final oldText = _controller.text;
                    final selection = _controller.selection;
                    final newText = oldText.replaceRange(selection.start, selection.end, hoge);
                    final newSelection = TextSelection.fromPosition(TextPosition(offset: selection.start + hoge.length));
                    _controller.value = _controller.value.copyWith(
                      text: newText,
                      selection: newSelection,
                    );
                    return KeyEventResult.handled;
                  }
                }
                return KeyEventResult.ignored;
              },
              child: TextField(
                controller: _controller,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

自分で試したこと

if (event is KeyDownEvent) {
    _controller.text = event.logicalKey.toString();

としたところ、日本語入力モードではキーイベント自体が発生していないようですが、どうすれば良いのかわかりません。

0

No Answers yet.

Your answer might help someone💌