Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reorder doesnt work when used in some pages in a carousel #118

Closed
charmosz opened this issue Sep 17, 2024 · 9 comments · Fixed by #119
Closed

reorder doesnt work when used in some pages in a carousel #118

charmosz opened this issue Sep 17, 2024 · 9 comments · Fixed by #119
Labels
bug Something isn't working

Comments

@charmosz
Copy link

Reordering works when the gridview is used in the first page of the carousel. But on next pages I can only drag. The reordering does not work. When I release an item it seems it comes back from the top (my carousel is vertical) and it stays at the same place.
It seems related to #83 . It works perfectly with 5.0.0-dev6 but not anymore with 5.0.0-dev7.

@karvulf
Copy link
Owner

karvulf commented Sep 17, 2024

Hallo @charmosz
Can you check if the issue still exists with the newest release 5.1.0 and can you send me the code which is not working?
And which flutter version do you use?

@charmosz
Copy link
Author

Hello ! Thanks for your quick reply.
The issue still exists with 5.1.0. I use flutter 3.24.3.
I can reorder in the two first pages but not in the next ones.

import 'package:flutter/material.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter_reorderable_grid_view/widgets/reorderable_builder.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({
    super.key,
  });

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
  final CarouselSliderController _carouselController = CarouselSliderController();
  final List<Widget> _pages = [];

  @override
  void initState() {
    super.initState();
    _pages.add(const SortPage(values: ["Element A1", "Element A2", "Element A3", "Element A4"]));
    // UNCOMMENT TO ADD ANOTHER CONTENT PAGE => the reordering will not work anymore for B elements
    //_pages.add(const Text("A page with some text"));
    _pages.add(const SortPage(values: ["Element B1", "Element B2", "Element B3", "Element B4"]));
    _pages.add(const SortPage(values: ["Element C1", "Element C2", "Element C3", "Element C4"]));
    _pages.add(const SortPage(values: ["Element D1", "Element D2", "Element D3", "Element D4"]));
  }

  @override
  Widget build(BuildContext context) {
    return PopScope(
      canPop: false,
      child: Scaffold(
        extendBody: true,
        body: Stack(
          children: <Widget>[
            CarouselSlider(
              carouselController: _carouselController,
              options: CarouselOptions(
                height: MediaQuery.of(context).size.height,
                enableInfiniteScroll: false,
                scrollDirection: Axis.vertical,
              ),
              items: _pages
            ),
          ],
        ),
      ),
    );
  }
}

class SortPage extends StatefulWidget {
  final List<String> values;

  const SortPage({
    super.key,
    required this.values,
  });

  @override
  State<SortPage> createState() => _SortPageState();
}

class _SortPageState extends State<SortPage> with AutomaticKeepAliveClientMixin {
  late List<String> _values;
  final _gridViewKey = GlobalKey();

  @override
  bool get wantKeepAlive => true;

  @override
  void initState() {
    super.initState();
    _values = List.from(widget.values);
    _values.shuffle();
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    final generatedChildren = List.generate(
      _values.length,
      (index) => ChildElement(
        key: Key(_values[index].toString()),
        text: _values[index],
      )
    );
    return Padding(
      padding: const EdgeInsets.all(0),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          const Text(
            'Drag and drop !',
            textAlign: TextAlign.center,
            style: TextStyle(
              fontStyle: FontStyle.italic,
            ),
          ),
          ReorderableBuilder(
            enableLongPress: false,
            enableScrollingWhileDragging: false,
            onReorder: (ReorderedListFunction reorderedListFunction) {
              print('reorder');
              setState(() {
                _values = reorderedListFunction(_values) as List<String>;
              });
            },
            onDragStarted: (intdex) => {
              print('start'),
              setState(() {
              })
            },
            onDragEnd: (intdex) => {
              print('end')
            },
            builder: (children) {
              return GridView.count(
                shrinkWrap: true,
                crossAxisCount: 1,
                childAspectRatio: 4,
                key: _gridViewKey,
                children: children,
              );
            },
            children: generatedChildren
          ),
        ],
      ),
    );
  }
}


class ChildElement extends StatelessWidget {
  const ChildElement({
    super.key,
    this.text,
  });

  final String? text;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 5),
      child: InkWell(
        borderRadius: BorderRadius.circular(8.0),
        child: Container(
          constraints: const BoxConstraints(
            minHeight: 50,
            maxHeight: 50
          ),
          padding: const EdgeInsets.all(5.0),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(8.0),
            border: Border.all(color: Colors.blue),
          ),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(text!),
            ],
          ),
        ),
      ),
    );
  }
}

@karvulf
Copy link
Owner

karvulf commented Sep 18, 2024

Thanks for the response, I will take a look on Saturday @charmosz

@karvulf karvulf added the bug Something isn't working label Sep 18, 2024
@karvulf
Copy link
Owner

karvulf commented Sep 21, 2024

Hello @charmosz
I found the issue and will release a fix with version 5.2.0 :)

@charmosz
Copy link
Author

Hi @karvulf . I tried with the new version on the same sample of code and unfortunately it does not fix the issue :/

@karvulf
Copy link
Owner

karvulf commented Sep 26, 2024

Oh ok I will check that on the weekend, thanks for the info @charmosz

@karvulf
Copy link
Owner

karvulf commented Sep 26, 2024

I just looked and it works for me with the sample code you gave me.
What exactly didn't work? And which phone did you use?
Can you also paste in what you got from flutter doctor -v?
@charmosz

The sample code I tried:

import 'package:flutter/material.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter_reorderable_grid_view/widgets/reorderable_builder.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({
    super.key,
  });

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
  final CarouselSliderController _carouselController =
      CarouselSliderController();
  final List<Widget> _pages = [];

  @override
  void initState() {
    super.initState();
    _pages.add(const SortPage(
        values: ["Element A1", "Element A2", "Element A3", "Element A4"]));
    // UNCOMMENT TO ADD ANOTHER CONTENT PAGE => the reordering will not work anymore for B elements
    //_pages.add(const Text("A page with some text"));
    _pages.add(const SortPage(
        values: ["Element B1", "Element B2", "Element B3", "Element B4"]));
    _pages.add(const SortPage(
        values: ["Element C1", "Element C2", "Element C3", "Element C4"]));
    _pages.add(const SortPage(
        values: ["Element D1", "Element D2", "Element D3", "Element D4"]));
  }

  @override
  Widget build(BuildContext context) {
    return PopScope(
      canPop: false,
      child: Scaffold(
        extendBody: true,
        body: Stack(
          children: <Widget>[
            CarouselSlider(
                carouselController: _carouselController,
                options: CarouselOptions(
                  height: MediaQuery.of(context).size.height,
                  enableInfiniteScroll: false,
                  scrollDirection: Axis.vertical,
                ),
                items: _pages),
          ],
        ),
      ),
    );
  }
}

class SortPage extends StatefulWidget {
  final List<String> values;

  const SortPage({
    super.key,
    required this.values,
  });

  @override
  State<SortPage> createState() => _SortPageState();
}

class _SortPageState extends State<SortPage>
    with AutomaticKeepAliveClientMixin {
  late List<String> _values;
  final _gridViewKey = GlobalKey();
  final _scrollController = ScrollController();

  @override
  bool get wantKeepAlive => true;

  @override
  void initState() {
    super.initState();
    _values = List.from(widget.values);
    _values.shuffle();
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    final generatedChildren = List.generate(
        _values.length,
        (index) => ChildElement(
              key: Key(_values[index].toString()),
              text: _values[index],
            ));
    return Padding(
      padding: const EdgeInsets.all(0),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          const Text(
            'Drag and drop !',
            textAlign: TextAlign.center,
            style: TextStyle(
              fontStyle: FontStyle.italic,
            ),
          ),
          ReorderableBuilder(
              scrollController: _scrollController,
              enableLongPress: false,
              enableScrollingWhileDragging: false,
              onReorder: (ReorderedListFunction reorderedListFunction) {
                print('reorder');
                setState(() {
                  _values = reorderedListFunction(_values) as List<String>;
                });
              },
              onDragStarted: (intdex) => {print('start'), setState(() {})},
              onDragEnd: (intdex) => {print('end')},
              builder: (children) {
                return GridView.count(
                  controller: _scrollController,
                  shrinkWrap: true,
                  crossAxisCount: 1,
                  childAspectRatio: 4,
                  key: _gridViewKey,
                  children: children,
                );
              },
              children: generatedChildren),
        ],
      ),
    );
  }
}

class ChildElement extends StatelessWidget {
  const ChildElement({
    super.key,
    this.text,
  });

  final String? text;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 5),
      child: InkWell(
        borderRadius: BorderRadius.circular(8.0),
        child: Container(
          constraints: const BoxConstraints(minHeight: 50, maxHeight: 50),
          padding: const EdgeInsets.all(5.0),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(8.0),
            border: Border.all(color: Colors.blue),
          ),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(text!),
            ],
          ),
        ),
      ),
    );
  }
}

@charmosz
Copy link
Author

I looked at the difference between the code I sent you and your code. I see that you add a scrollController. That makes the difference. It works now ;). Thanks

@karvulf
Copy link
Owner

karvulf commented Sep 27, 2024

Ah sry for that I totally forgot that I did it 😅 @charmosz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants