-1

I would like to scroll to a particular row (containing the day of week name), but these rows are separated by differents widgets, so I can't put them in a ListView and use an index to scroll, here is a part of my code where you can see the row for monday and the row for tuesday separated by 3 widgets :

Row(
                              mainAxisAlignment: MainAxisAlignment.start,
                              children: [
                                buildHorizontalSpace(10.0),
                                Text(
                                  "Monday :",
                                  style: BeoStyles.whiteSubtitle,
                                )
                              ]
                            ),
                            buildVerticalSpace(10.0),
                            buildDayTasks(1),
                            buildVerticalSpace(10.0),
                            Row(
                              mainAxisAlignment: MainAxisAlignment.start,
                              children: [
                                buildHorizontalSpace(10.0),
                                Text(
                                  "Tuesday :",
                                  style: BeoStyles.whiteSubtitle,
                                )
                              ]
                            ),

If you have an idea on how to do that you are more than welcome !

JS1
  • 631
  • 2
  • 7
  • 23
  • 1
    You can convert row to ListView. You can review this post : [Flutter: Scrolling to a widget in ListView](https://stackoverflow.com/a/58435822/10187218) – Yasin Ege Feb 03 '22 at 09:35
  • Did you see this post elsewhere on SO? https://stackoverflow.com/a/49154882/15469537 It looks to work for your problem – fravolt Feb 03 '22 at 09:45
  • @YasinEge well the problem is that my rows are separated by other widgets so I would need to include these on the listView, I tried it here : https://stackoverflow.com/questions/70959339/flutter-scrollablepositionedlist-doesnt-work but had an error – JS1 Feb 03 '22 at 10:42
  • @fravolt tried it, kind of work in the sense that it was scrolling proportionally to the position of the row I choose, but still far from the exact position, like when I scrolled for friday which lower than tuesday, the scroller also go farther low than the one for tuesday, but it still doesn't go all the way to friday – JS1 Feb 03 '22 at 10:44
  • probably you are using a `SingleChildScrollView` to scroll then give a scroll controller to it and use `animateTo` function, you have to calculate offset for this – Pokaboom Feb 03 '22 at 10:51
  • Hey @JS1, I just got it working in my example app, check out if it works in my answer below :) – fravolt Feb 03 '22 at 12:27

1 Answers1

0

Using Scrollable.ensureVisible as described in the other SO post, I managed to get it working in an example app. Let me know if it works for you.

import 'dart:math';

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // Seven keys is manageable
  List<GlobalKey> dayKeys = [
    GlobalKey(),
    GlobalKey(),
    GlobalKey(),
    GlobalKey(),
    GlobalKey(),
    GlobalKey(),
    GlobalKey(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: SingleChildScrollView(
        child: Column(
          // days and in-between widgets
          children: [
            buildFiller(),
            buildFiller(),
            buildDayWidget(day: 'Monday', key: dayKeys[0]),
            buildFiller(),
            buildFiller(),
            buildDayWidget(day: 'Tuesday', key: dayKeys[1]),
            buildFiller(),
            buildFiller(),
            buildDayWidget(day: 'Wednesday', key: dayKeys[2]),
            buildFiller(),
            buildFiller(),
            buildDayWidget(day: 'Thursday', key: dayKeys[3]),
            buildFiller(),
            buildFiller(),
            buildDayWidget(day: 'Friday', key: dayKeys[4]),
            buildFiller(),
            buildFiller(),
            buildDayWidget(day: 'Saturday', key: dayKeys[5]),
            buildFiller(),
            buildFiller(),
            buildDayWidget(day: 'Sunday', key: dayKeys[6]),
            buildFiller(),
            buildFiller(),
          ],
        ),
      ),
      floatingActionButton: Column(children: [
        FloatingActionButton(
          onPressed: () => _scrollToDay(0),
          tooltip: 'Monday',
          child: const Text('1'),
        ),
        const SizedBox(height: 4,),
        FloatingActionButton(
          onPressed: () => _scrollToDay(1),
          tooltip: 'Tuesday',
          child: const Text('2'),
        ),
        const SizedBox(height: 4,),
        FloatingActionButton(
          onPressed: () => _scrollToDay(2),
          tooltip: 'Wednesday',
          child: const Text('3'),
        ),
        const SizedBox(height: 4,),
        FloatingActionButton(
          onPressed: () => _scrollToDay(3),
          tooltip: 'Thursday',
          child: const Text('4'),
        ),
        const SizedBox(height: 4,),
        FloatingActionButton(
          onPressed: () => _scrollToDay(4),
          tooltip: 'Friday',
          child: const Text('5'),
        ),
        const SizedBox(height: 4,),
        FloatingActionButton(
          onPressed: () => _scrollToDay(5),
          tooltip: 'Saturday',
          child: const Text('6'),
        ),
        const SizedBox(height: 4,),
        FloatingActionButton(
          onPressed: () => _scrollToDay(6),
          tooltip: 'Sunday',
          child: const Text('7'),
        ),
      ],
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.end,
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
    );
  }

  void _scrollToDay(int day) {
    // scroll to a specific day
    Scrollable.ensureVisible(dayKeys[day].currentContext!);
  }

  Widget buildDayWidget({required String day, required GlobalKey key}) {
    return ListTile(
      key: key,
      title: Text(day),
      subtitle: Text('This is a widget giving you an overview of the different tasks of $day', softWrap: true,),
    );
  }

  Widget buildFiller() {
    return Container(
      color: Color.fromARGB(255, Random().nextInt(255), Random().nextInt(255), Random().nextInt(255)),
      width: double.maxFinite,
      height: 200,
    );
  }
}

fravolt
  • 2,565
  • 1
  • 4
  • 19
  • I tried it, when I use buttons like you did it works fine, but I personnaly want the scroll to happen the widget is built, so I put the logic in WidgetsBinding.instance!.addPostFrameCallback((_) as a function of today's weekday, and it's where the scroll doesn't work correctly – JS1 Feb 03 '22 at 14:31
  • Here is the logic I put inside widgetbinding => switch (today.weekday) { case 1: Scrollable.ensureVisible(mondayKey.currentContext!); break; case 2: Scrollable.ensureVisible(tuesdayKey.currentContext!); break; case 3: Scrollable.ensureVisible(wednesdayKey.currentContext!); break; case 4: Scrollable.ensureVisible(thursdayKey.currentContext!); break; case 5: Scrollable.ensureVisible(fridayKey.currentContext!); break; } – JS1 Feb 03 '22 at 14:32