TextFieldのちらつきを解消したい – 開発日記(87)

アイディアの入力方法を改善したが…… 2024/04/09

アイディアにフォーカスしている状態でキーボードから文字入力を開始したときに、自動的にReadOnlyが外れて文字が入るようにした。

これまではEnterを押したときだけ編集モードにしていた。そのためまずEnterを押す→編集モードになる→文字入力開始となっていた。
これを編集モードなど関係なく、キーボードのaなどを普通に押したときは自然に文字入力が始まってかつ編集モードに入るようにした。

と書くと簡単そうに見えるが、非常に苦戦した。

というのもこれまで描画の軽量化のため、アイディアはTextFieldではなくTextField”風”のContaierを描画していた。(InputDecorator利用)。そしてアイディアでEnterキーを押すなどして編集モードに入ったときに、こっそりTextFieldに描画を切り替えていた。

ただこのやり方だと「Containerのときにキーボードを打ち始めた最初の1文字を検知し、描画したTextFieldに渡す」などという芸当はうまく出来なかった。

そこで初めからTextFieldを描画する形に変更。
といってももちろん画面上の全てのアイディアをTextFieldで描画するとパフォーマンスが悪くなるので、フォーカスしたアイディアのみTextField、それ以外はTextField”風”のContaierという形にした。

ところがこれでハマる。
TextFieldはfilledがtrueのときにマウスインすると自動で色が変わるのだが、このせいでマウスのホバーIN/OUTのたびに描画がちらついて見える。
fillColor と hoverColorを同じにしてやはりもちらつく。

TextFieldのソースを頑張って見ていくと、マウスオーバー(in/out)で isHoveringフラグがtrue/falseに切り替わり setState()が走る。

場所としては text_field.dart内のvoid _handleHover(bool hovering) の部分。
ちらつきを押さえたいので、この処理を止めたい。

だが出来ない。というのもソースを追ったが全部private関数のため、このWidgetを継承したとしても変えられない。というかそもそもStateがプライベートなので継承も出来ない。
つまりTextFieldをマウスオーバーしたときに「ちらつき防止のためsetStateさせない」という制御が外から出来ず、継承も出来ない。

困った……。

かなり悪手だがTextFielde2のようなコピーを作ってなんとかするしか無いか?

そしてこれはイシューとして上がっていた。

TextField flickers gray on hover on web when filled is set to true and fillColor and hoverColor are set to white · Issue #132373 · flutter/flutter

現時点ではOpenのままだったが、同じことで困っている人たちがなんとワークアラウンド(回避策)を発見してくれていた。

hoverColor: Colors.transparent を指定するというシンプルなものだがうまく機能する!なるほど!setState()自体が走ることは変わらないのでイマイチだが、見た目的には大丈夫になった。助かった…。

この問題、そもそもWidgetの一部だけ継承できれば解決するし色々便利なのだけれど、Flutterの標準Widgetはそういったことがやりづらく融通が利かない印象がある。

2024/04/10~04/12

様々な挙動改善や不具合修正を行った。

  • アイディア上でキーボードから文字入力を開始したときに、自動的にReadOnlyが外れるようにする処理の続き。
  • アイディアの描画ウィジェットを大きく変えたので、キャンバス内検索をしたときのハイライトの処理もそれに合わせた形に対応。
  • アイディアのUndo/Redoに関わるフォーカス制御の修正
  • クリップボードからのペースト機能を実装。
  • レーン削除の際に、DB側への反映がうまくいかない場合があった不具合を修正


※開発日記は当時の記録をもとに作成し、必要に応じて加筆・補足しています

この記事はアイディア整理ソフト「idea Lane」の開発記録です

どなたでも、ユーザ登録だけで無料ですぐに使えます
テキストベースの思考整理ツール「idea Lane」


コメント

タイトルとURLをコピーしました