I am using ScrollablePositionedList(scrollable_positioned_list) for moving to a particular position in a list.

The scenario is, when we open the page in the application, the list will be automatically scrolling. If I try to manually scroll the list, it is not possible because the list is in the process of auto scrolling.

So, is there any way to stop the auto scrolling when I try to drag or swipe the list manually.


Solution 1: Tasnuva Tavasum oshin

1st add this in your list:

physics: NeverScrollablePhysics();

so now your list will not scroll manually or drag time ,

then add controller so that you can auto scroll the list . add this controller in the init method.

Example:

     import 'dart:async';

import 'package:faker/faker.dart';
import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

part '66455867.auto_scroll.freezed.dart';

void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      home: HomePage(),
    ),
  );
}

class HomePage extends StatelessWidget {
  Future<List<News>> _fetchNews() async => dummyData;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('News')),
      body: FutureBuilder(
        future: _fetchNews(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return NewsList(newsList: snapshot.data);
          } else if (snapshot.hasError) {
            return Center(child: Text(snapshot.error.toString()));
          } else {
            return Center(child: CircularProgressIndicator());
          }
        },
      ),
    );
  }
}

class NewsList extends StatefulWidget {
  final List<News> newsList;

  const NewsList({
    Key key,
    this.newsList,
  }) : super(key: key);

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

class _NewsListState extends State<NewsList> {
  ScrollController _scrollController = ScrollController();
  Timer _timer;

  double _itemExtent = 100.0;
  Duration _scrollDuration = Duration(milliseconds: 300);
  Curve _scrollCurve = Curves.easeInOut;

  int _autoScrollIncrement = 1;
  int _currentScrollIndex = 0;

  @override
  void initState() {
    super.initState();
    _timer = Timer.periodic(Duration(seconds: 2), (_) async {
      _autoScrollIncrement = _currentScrollIndex == 0
          ? 1
          : _currentScrollIndex == widget.newsList.length - 1
              ? -1
              : _autoScrollIncrement;
      _currentScrollIndex += _autoScrollIncrement;
      _animateToIndex(_currentScrollIndex);
      setState(() {});
    });
  }

  void _animateToIndex(int index) {
    _scrollController.animateTo(
      index * _itemExtent,
      duration: _scrollDuration,
      curve: _scrollCurve,
    );
  }

  @override
  void dispose() {
    _timer?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return ListView(
      controller: _scrollController,
      physics: NeverScrollablePhysics();
      itemExtent: _itemExtent,
      children: widget.newsList
          .map((news) => ListTile(
                title: Text(news.title),
                subtitle: Text(
                  news.description,
                  maxLines: 1,
                  overflow: TextOverflow.ellipsis,
                ),
                selected: widget.newsList[_currentScrollIndex].id == news.id,
                selectedTileColor: Colors.amber.shade100,
              ))
          .toList(),
    );
  }
}

@freezed
abstract class News with _$News {
  const factory News({int id, String title, String description}) = _News;
}

final faker = Faker();
final dummyData = List.generate(
  10,
  (index) => News(
    id: faker.randomGenerator.integer(99999999),
    title: faker.sport.name(),
    description: faker.lorem.sentence(),
  ),
);