Flutter: LeaderLayer anchor must come before FollowerLayer in paint order, but the reverse was true.のエラー
  
  
  
  結論:テキスト編集中は、ドラッグできないよう制御する
2022/4/30 Flutter エラー・バグ日記
ドラッグでリスト要素の並べ替えができる「ReorderableListView」を導入したところ、エラーが発生。
各リスト要素をCardクラスとし、その子要素としてTextFormFieldを設置していたが、テキスト編集中の状態のまま(TextFormFieldにフォーカスが当たったまま)、Cardをドラッグしようとすると、以下のエラーが発生してしまう。
LeaderLayer anchor must come before FollowerLayer in paint order, but the reverse was true.
'package:flutter/src/rendering/layer.dart':
Failed assertion: line 2502 pos 7: 'leader._lastOffset != null'
TextFormFieldにフォーカスが当たっていなければ、エラーは生じず、問題なくドラッグできる。
レンダリングしようとしているレイヤーに問題がある、ということ?みたいだが、、、ソースを見ても理解できず。。
仕方なくエラーメッセージでググるが、概ね以下2つの情報しか見つからず、自分のケースとは事情が異なっていた。
- リスト要素内に「Slider」を使っている時に発生 → 「CupertinoSlider」に変えれば解消
 - テキストを選択した状態でドラッグすると発生 → Flutterのバージョンを上げれば解消
 
そのため、仕方なくテキスト編集中は、ドラッグできないよう制御を入れることにした。
「ReorderableListView」のソースを見ていると、「buildDefaultDragHandles」というプロパティがあると分かったので、これを「false」に変更し、「ReorderableDragStartListener」を用いて、Card上の特定のIconだけが、ドラッグのハンドル(つかむ部分)になるよう変更した。
※こちらの公式説明によると、デフォルトでは「buildDefaultDragHandles」は「true」になっており、ドラッグのハンドルは、リスト要素全体(どこでもつかめる状態)に設定されているらしい。
また、ハンドルとなるIconを「GestureDetector」でラップし、テキスト編集中にドラッグしようとすると、「テキスト編集中はドラッグできません」というトーストメッセージを出そうとした。
しかし、ドラッグを開始しても、「GestureDetector」に設置した「onTap」や「onLongPress」属性を発動できなかった。どうやら、ドラッグと、タップ・長押しは、根本的に違うアクションの位置づけらしい。
試行錯誤の末、「onPanDown」であれば、ドラッグしようとした時に、Iconのタップも検知できると分かったので、「onPanDown」属性に、トーストメッセージを表示するメソッドを設置することで、なんとか解決できた。
※該当箇所のソースコード例は以下
ReorderableListView.builder(
            // リスト要素全体がドラッグのハンドルにならないようにする
            buildDefaultDragHandles: false,
            itemBuilder: (BuildContext context, int indexO) {
              return Card(
                key: Key('$indexO'),
                child: GestureDetector(
                  onPanDown: (detailsO) {
                    // ドラッグを開始した時に、並べ替え以外で発動したい処理を書く
                  },
                  // ドラッグできるハンドルを以下のIconに限定する
                  child: ReorderableDragStartListener(
                    index: indexO,
                    child: Icon(Icons.drag_handle),
                  ),
                ),
              );
            },
            itemCount: 10,
            onReorder: (int oldIndexO, int newIndexO) {
              // 略: 並び替えに必要な処理を書く(リスト変数の更新など)
            },
        );
リリースしたアプリ(全てFlutterで開発)
個人アプリ開発で役立ったもの
おすすめの学習教材
\超初心者向けでオススメな元Udemyの講座/
\キャンペーン時を狙えば安価で網羅的な内容が学べる(日本語訳あり)/
\Gitの基礎について無料で学べる/
おすすめの学習書籍
\実用的。image_pickerに関してかなり助けられた/
\Dartの基礎文法を素早くインプットできる/




