How to autocorrect scroll position in a listview? (flutter)

Viewed 2336

I have a horizontal listviewbuilder as shown in the picture on the top:Listview is on the top of the screen where you can see the dates. In this picture, I scrolled a bit and stopped at this position

Is there a way to autocorrect the current position so that the widget on the right corner fits perfectly to his full width? (here number 27)Because if you stop scrolling, it doesn't look nice if it is cut out like the number 27 in the picture. So is it possible to stop only on the fullest itemwidget so that the current position will not be like in the picture?

Here is my code for the listview builder:

import './date_widget.dart';


import 'package:date_picker_timeline/gestures/tap.dart';
import 'package:flutter/material.dart';
import 'package:intl/date_symbol_data_local.dart';

class MyDatePickerTimeline extends StatefulWidget {
 

  
  
  DateTime currentDate;
  DateChangeListener onDateChange;
 
  String locale;

  // Creates the DatePickerTimeline Widget
  MyDatePickerTimeline(
    this.currentDate, {
    Key key,
    
   
    
    
    
    this.onDateChange,
    this.locale = "de",
  }) : super(key: key);

  @override
  State<StatefulWidget> createState() => new _MyDatePickerTimelineState();
}

class _MyDatePickerTimelineState extends State<MyDatePickerTimeline> {

  @override void initState() {
    super.initState();

    initializeDateFormatting(widget.locale, null);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      
     // padding: EdgeInsets.only(bottom: 600),
      width: MediaQuery.of(context).size.width ,
      height: 200,
      child: ListView.builder(
        reverse: true,
        itemCount: 5000,
        scrollDirection: Axis.horizontal,
        itemBuilder: (context, index) {
          // Return the Date Widget
          DateTime _date = DateTime.now().subtract(Duration(days: index));
          DateTime date = new DateTime(_date.year, _date.month, _date.day);
          bool isSelected = compareDate(date, widget.currentDate);

          return MyDateWidget(
            date: date,
           
            locale: widget.locale,
            selectionColor:
                isSelected ? Colors.black12 : Colors.transparent,
            onDateSelected: (selectedDate) {
              // A date is selected
              if (widget.onDateChange != null) {
                widget.onDateChange(selectedDate);
              }
              setState(() {
                widget.currentDate = selectedDate;
              });
            },
          );
        },
      ),
    );
  }

  bool compareDate(DateTime date1, DateTime date2) {
    return date1.day == date2.day &&
        date1.month == date2.month &&
        date1.year == date2.year;
  }
}

Or is it possible to set a fixed width that you can scroll?

1 Answers

It seems that you are looking for PageScrollPhysics. From the PageScrollPhysics class documentation:

Scroll physics used by a PageView. These physics cause the page view to snap to page boundaries.

Having your ListView's physics property set to PageScrollPhysics will make the list scroll in a paginated, discrete way. If you also set the width of the widgets inside your ListView equal a fraction of the screen width, then the widgets inside the ListView will never be cut, no matter how many items there are in the list, how big the screen gets, or how the user scrolls.

Check out this sample I wrote to show you a way to implement this kind of scroll physics. You can copy it and run it in DartPad to see if it is what you are looking for. Note that there are 3 entries per page scrolled, yet there are 7 entries total in the ListView, and there is no way to have any of them cut in the view.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView(
        physics: PageScrollPhysics(),
        scrollDirection: Axis.horizontal,
        children: <Widget>[
          Container(
            width: MediaQuery.of(context).size.width/3,
            color: Colors.amber[900],
            child: const Center(child: Text('Entry A')),
          ),
          Container(
            width: MediaQuery.of(context).size.width/3,
            color: Colors.amber[800],
            child: const Center(child: Text('Entry B')),
          ),
          Container(
            width: MediaQuery.of(context).size.width/3,
            color: Colors.amber[700],
            child: const Center(child: Text('Entry C')),
          ),
          Container(
            width: MediaQuery.of(context).size.width/3,
            color: Colors.amber[600],
            child: const Center(child: Text('Entry D')),
          ),
          Container(
            width: MediaQuery.of(context).size.width/3,
            color: Colors.amber[500],
            child: const Center(child: Text('Entry E')),
          ),
          Container(
            width: MediaQuery.of(context).size.width/3,
            color: Colors.amber[400],
            child: const Center(child: Text('Entry F')),
          ),
          Container(
            width: MediaQuery.of(context).size.width/3,
            color: Colors.amber[300],
            child: const Center(child: Text('Entry G')),
          ),
        ],
      ),
    );
  }
}

Related