🌘

Flutter Web使うときのメモ

2 min read

テキストが選べない

普通のwebサイトは文字の上をドラッグすると選択できてコピーとかペーストできると思うのですが、Textウィジェットを使用すると選択できないです。

解決法

TextウィジェットではなくSelectableTextウィジェットを使用する。

https://api.flutter.dev/flutter/material/SelectableText-class.html
SelectableTextウィジェットはTextFieldから内容を変更する機能を取り払ったようなもので、結構思い通りに動いてくれます。

ブラウザごとの挙動の制御に困る

Edgeのパスワードフォームの目を消したいというのがありました(以下を消すのをFlutterWebでやりたい)

https://social.msdn.microsoft.com/Forums/ja-JP/89ba3b0e-084d-442b-b0e6-63f8e2f22787?threadDisplayName=1248612461124731248812508124831246312473124971247312527125401&forum=edgeiesupportteamja

解決法

dart:htmlで無理やり書き換える。

    final nodeValidatorBuilder = NodeValidatorBuilder.common()
      ..allowElement('style');
      
    document.querySelector('head').insertAdjacentHtml(
          'beforeend',
          '''
        <style>
          input::-ms-reveal,
          input::-ms-clear{
            display: none;
          }
        </style>
        ''',
          validator: nodeValidatorBuilder,
        );

FlutterWebの機能のみでブラウザごとの挙動を制御することは無理(多分)なのでdart:htmlでcssを追加します。以下補足。

  • cssを追加する際に以下の設定をしておかないとエラーが出る
final nodeValidatorBuilder = NodeValidatorBuilder.common()..allowElement('style');

参考) https://stackoverflow.com/questions/60276170/use-js-library-in-flutter-web

  • 本文。headの、最後に、指定したhtml、を追加する感じ。今回はEdgeの目のマーク(reveal)とIEのバツボタン(clear)を消してる。
document.querySelector('head').insertAdjacentHtml(
          'beforeend',
          '''
        <style>
          input::-ms-reveal,
          input::-ms-clear{
            display: none;
          }
        </style>
        ''',
          validator: nodeValidatorBuilder,
        );

リロード(F5)押されると持ってる状態が消える

F5押されるとChangeNotifierやBlocに持ってる要素がリセットされます。ネイティブアプリ作ってるときは気にしなくて良い要素というかFlutterしか触ったことないのでつまづきました。

解決法

sessionStorageを利用する。以下参考にjsのページですがdart版がdart:htmlで使えます。

https://developer.mozilla.org/ja/docs/Web/API/Window/sessionStorage
以下使用例
  • 保存するとき
// オブジェクトをJsonでsessionStorageに保存
final aaaaJsonMap = aaaaObject.toJson();
window.sessionStorage['キー1'] = jsonEncode(aaaaJsonMap);
  • 取り出すとき
// sessionStorageからJson取り出してオブジェクト生成
final aaaaJsonMap = jsonDecode(window.sessionStorage['キー1']);
final aaaaObject = AaaaObject.fromJson(aaaaJsonMap);

// お使いの状態管理の何かに入れる
final aaaaBloc = AaaaBloc.fromObject(aaaaObject);

大体全部sessionStorageに保存しておけば上手くいく気がする。でもWebやってる人ならもっと詳しいのではと思った。

感想

Webも基本的にFlutterそのままの書き方で書けちゃうのはすごいと思った。
ただ気をつけないとすぐに重くなってしまったり(Webだと一画面のWidgetが多くなるため)結局html書かないとできないことがあったりする。