Flutter scrollable_positioned_list does not handle the index correctly

52 Views Asked by At

I am trying to create the vertical list of items (Containers) of different height which could be scrolled to the fixed position with ScrollablePositionedList.builder. To manage my list of items, I want to use buttons located in horizontal (also scrollable) menu, one button (for instance, "About object") for one specific widget (for instance, _aboutObject). Now my code looks like that:

...
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
...

class _SaleOfficeState extends State<SaleOffice> {
  final itemController = ItemScrollController(); // for body
  final List<String> menuItems = ["Location", "About object"];

  Future scrollToItem(int index) async {
    itemController.scrollTo(
      index: index,
      alignment: 0,
      duration: Duration(seconds: 1),
    );
  }

  Widget _location() {Container(...)}

  Widget _aboutObject() {Container(...)}

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        // AppBar definition
      ),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Container(
            // Top menu container
            height: 50,
            child: ListView.builder(
              scrollDirection: Axis.horizontal,
              itemCount: menuItems.length,
              itemBuilder: (BuildContext context, int index) {
                return Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: TextButton(
                    onPressed: () {
                      print("top menu button is pressed");
                      scrollToItem(index); 
                    },
                    child: Text(
                      menuItems[index],
                    ),
                  ),
                );
              },
            ),
          ),
          Expanded(
            child: ScrollablePositionedList.builder(
              itemCount: menuItem.length, 
              itemScrollController: itemController,
              itemBuilder: (BuildContext context, int index) {
                  if (index == 0) {
                    return _location();
                  } else if (index == 1) {
                    return _aboutObject();
                  }
                  return Container();
                },
            ),
          ),
        ],
      ),
    );
  }
} 

It scrolls correctly when I press the relevant button with needed duration, but immediately goes back to the starting position. I want it to be pinned on the upper position, until another button is presses.

Another strange behavior is: if I use non-existent index, for instance, 2:

   await Scrollable.ensureVisible(context);
   itemController.scrollTo(
       index: 2,
       alignment: 0,
       duration: Duration(seconds: 1),
   );
 }

the code reacts and do the same as with index: index. It seems I do not understand how this scrollable_positioned_list works. Any advices are highly appreciated.

1

There are 1 best solutions below

0
AmirHossein On

You can get index of selected item and then remove that item from your list and insert that removed item into your list(now it appears as the first element in your list).

for example, selected item index is 5

myList.removeAt(5)  // 5 is your selected item index

then

myList.insert(0, element)  // element is type of your list(if your list type 
   //is string then element type will be string like "A" if it is a model 
   //class, then it will be model class)

Happy Coding :)