Flutter: LeaderLayer anchor must come before FollowerLayer in paint order, but the reverse was true.のエラー

※当サイトは、アフィリエイト広告を利用しています

結論:テキスト編集中は、ドラッグできないよう制御する

2022/4/30 Flutter エラー・バグ日記

 

ドラッグでリスト要素の並べ替えができる「ReorderableListView」を導入したところ、エラーが発生。

 

本記事はライトな日記思考で書いているので、詳細説明はしておらず、基本、テキストのみで画像とかは載せておりません。。m(_ _)m

解説記事ではないため、解決していない内容や、その時々の間違った解釈を述べてしまっている可能性が大いにありますので、何卒、ご了承ください。

 

各リスト要素を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の基礎文法を素早くインプットできる/


Dart入門 - Dartの要点をつかむためのクイックツアー

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