简体   繁体   中英

ReorderableListView throws when Slider in item list

I've got a ReorderableListView where the ListTile contains a Slider() widget. If I don't touch any of the Slider() widgets, I can reorder the ListTiles with no issue. But, as soon as you click-on or interact with any of the Slider() widgets, then attempting to reorder the items throws() with this error in the debug console (many of them):

════════ Exception caught by scheduler library ═════════════════════════════════
Assertion failed:
../…/rendering/layer.dart:2498
leader._lastOffset != null
"LeaderLayer anchor must come before FollowerLayer in paint order, but the reverse was true."

On Flutter 2.8.1, Stable Channel.

Here is the code to duplicate. I used the example code from the ReorderableListView widget documentation, and the only things I changed was the Text() to a Slider() as well as autogenerate some values for the Slider(). Other than that it's the same example as the documentation. This works fine with a Text() widget, but the Slider() fails. Is there a way to use a Slider() inside a ReorderableListView()?:

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

const Color darkBlue = Color.fromARGB(255, 18, 32, 47);

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark().copyWith(
        scaffoldBackgroundColor: darkBlue,
      ),
      debugShowCheckedModeBanner: false,
      home: const Scaffold(
        body: Center(
          child: ListViewTestWidget(),
        ),
      ),
    );
  }
}

class ListViewTestWidget extends StatefulWidget {
  const ListViewTestWidget({Key? key}) : super(key: key);

  @override
  _ListViewTestWidgetState createState() => _ListViewTestWidgetState();
}

class _ListViewTestWidgetState extends State<ListViewTestWidget> {
  final List<int> _items = List<int>.generate(50, (int index) => index);
  final List<double> _values =
      List<double>.generate(50, (int index) => Random().nextDouble() * 100);

  _changeValue(int index, double newValue) {
    if (newValue < 1 || newValue > 100) return;
    setState(() {
      _values[index] = newValue;
    });
  }

  @override
  Widget build(BuildContext context) {
    final ColorScheme colorScheme = Theme.of(context).colorScheme;
    final Color oddItemColor = colorScheme.primary.withOpacity(0.05);
    final Color evenItemColor = colorScheme.primary.withOpacity(0.15);

    return ReorderableListView(
      padding: const EdgeInsets.symmetric(horizontal: 40),
      children: <Widget>[
        for (int index = 0; index < _items.length; index += 1)
          ListTile(
            key: Key('$index'),
            tileColor: _items[index].isOdd ? oddItemColor : evenItemColor,
            title: Slider(
              min: 1,
              max: 100,
              value: _values[index],
              onChanged: (newValue) =>
                  setState(() => _changeValue(index, newValue)),
            ),
          ),
      ],
      onReorder: (int oldIndex, int newIndex) {
        setState(() {
          if (oldIndex < newIndex) {
            newIndex -= 1;
          }
          final int item = _items.removeAt(oldIndex);
          _items.insert(newIndex, item);
        });
      },
    );
  }
}

This is a known issue on the flutter framework itself. You can track the progress of this issue on GitHub: https://github.com/flutter/flutter/issues/97292

Meanwhile (before they fix it), you can perhaps try to use CupertinoSlider to replace the (Material) Slider . The issue does not occur on the Cupertino widget. And yes, they look a little different but the main functionalities are the same. Or you can write your own slider widget and customize it however you want.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM