Skip to content

Instantly share code, notes, and snippets.

@flameoftheforest
Created January 2, 2024 05:12
Show Gist options
  • Save flameoftheforest/e208e6af656ad83507b13d7d633b3202 to your computer and use it in GitHub Desktop.
Save flameoftheforest/e208e6af656ad83507b13d7d633b3202 to your computer and use it in GitHub Desktop.
Modified ListWheelScrollView
//
// README
// + I do not claim any credits to the code
// + Please refer to the links to find the original codes
//
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() => runApp(MyApp());
// https://gist.github.com/mohammedsalem97/e8c93d9691167024122a2eda1dfa92e3
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({super.key, required this.title});
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar:AppBar(
title:Text("Wheel test"),
),
backgroundColor:Colors.red,
body:ListWheelScrollView.useDelegate(
itemExtent: 100.0,
// clipToSize: true,
diameterRatio: 0.35,
magnification: 1,
overAndUnderCenterOpacity: 0.5,
offAxisFraction: 0,
// useMagnifier: true,
physics: PagingScrollPhysics(itemCount: 30, viewSize: 100),
onSelectedItemChanged: (i) => print("Changed $i"),
renderChildrenOutsideViewport: false,
squeeze: 1.5,
childDelegate: ListWheelChildBuilderDelegate(
builder: (context,index){
return Container(
color:Colors.white,
width:MediaQuery.of(context).size.width/3,
child: ListTile(
title:Text(index.toString()),
trailing:Icon(Icons.home),
),
);
},
childCount: 30,
),
),
);
}
}
// https://stackoverflow.com/a/72817531/1989698
class PagingScrollPhysics extends ScrollPhysics {
const PagingScrollPhysics(
{required this.itemCount, required this.viewSize, super.parent});
final double viewSize;
final int itemCount;
@override
PagingScrollPhysics applyTo(ScrollPhysics? ancestor) => PagingScrollPhysics(
itemCount: itemCount, viewSize: viewSize, parent: buildParent(ancestor));
double _getPage(double current, double itemDimension) =>
current / itemDimension;
double _getTargetPixels(
ScrollMetrics position, Tolerance tolerance, double velocity) {
// plus view size because the max scroll extent is about where the screen
// starts not where the screen ends.
final pixels = position.maxScrollExtent + viewSize;
final itemDimension = pixels / itemCount;
var page = _getPage(position.pixels, itemDimension);
if (velocity < -tolerance.velocity)
page -= 0.5;
else if (velocity > tolerance.velocity) page += 0.5;
final pageRound = page.round();
final itemsPerPage = viewSize ~/ itemDimension;
final showingLastItem = pageRound == itemCount - itemsPerPage;
if (showingLastItem) return pixels - viewSize;
return pageRound * itemDimension;
}
@override
Simulation? createBallisticSimulation(
ScrollMetrics position, double velocity) {
if ((velocity <= 0.0 && position.pixels <= position.minScrollExtent) ||
(velocity >= 0.0 && position.pixels >= position.maxScrollExtent))
return super.createBallisticSimulation(position, velocity);
final Tolerance tolerance = this.tolerance;
final double target = _getTargetPixels(position, tolerance, velocity);
if (target != position.pixels)
return ScrollSpringSimulation(spring, position.pixels, target, velocity,
tolerance: tolerance);
return null;
}
@override
bool get allowImplicitScrolling => false;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment