ListWheelScrollView Flutter Example
Last updated Aug 25, 2020How to create Wheel view in a flutter, How we can achieve to display items in like wheel design.
Flutter provided a widget called ListWheelScrollView, which will use to display items in Wheel with animation.
What is ListWheelScrollView?
ListWheelScrollView
is a widget which aligns all its children in a scrollable wheel. That results in a 3D effect as if the children are rotating in a wheel. The currently selected item will be in the center wheel. In this example we will learn how to create a ListWheelScrollView
including how to customize the look and how to handle when the selected item changes.
Create ListWheelScrollView
ListWheelScrollView
has default constructor to create
ListWheelScrollView.
This contains 2 required parameters children
(List<Widget>
) and itemExtent
(double
)
children: The child items which we are going to display
itemExtent
: size of each child item
|
Example
Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
elevation: 4,
color: Colors.grey,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Container(
color: Colors.white,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text("Day of Week",style: TextStyle(color: Colors.green,fontWeight: FontWeight.bold,fontSize: 20),),
Container(
width: 200,
height: 180,
child: ListWheelScrollView(
useMagnifier: true,
magnification: 1.2,
diameterRatio: 3,
itemExtent: 50,
onSelectedItemChanged: (index){
},
physics: FixedExtentScrollPhysics(),
children: [
getWeekDay("Sunday"),
getWeekDay("Monday"),
getWeekDay("Tuesday"),
getWeekDay("Wednesday"),
getWeekDay("Thursday"),
getWeekDay("Friday"),
getWeekDay("Sateday")
],
),
)
],
),
),
),
),
)
getWeekDay(day)
{
return Container(
decoration: BoxDecoration(
border: Border(
top: BorderSide(color: Colors.green,width: 1),
)
),
child: ListTile(
title: Text(day,textAlign: TextAlign.center,style: TextStyle(fontSize: 20),),
),
);
}
|
We have another way to create a ListWheelScrollView
by using .useDelegate()
named constructor. Instead of passing children
, you need to pass a ListWheelChildDelegate
to build the children
Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
elevation: 4,
color: Colors.grey,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Container(
color: Colors.white,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
width: 50,
height: 100,
child: ListWheelScrollView.useDelegate(
childDelegate: ListWheelChildBuilderDelegate(
childCount: days.length,
builder: (BuildContext context, int index) {
if (index < 0 || index > days.length) {
return null;
}
return Container(
decoration: BoxDecoration(
border: Border(
top: BorderSide(color: Colors.green,width: 1),
)
),
child: ListTile(
title: Text(days[index].toString(),style: TextStyle(fontSize: 20)),
),
);
}),
useMagnifier: true,
magnification: 1.2,
diameterRatio: 3,
itemExtent: 50,
onSelectedItemChanged: (index){
},
physics: FixedExtentScrollPhysics(),
),
),
Container(
width: 100,
height: 180,
child: ListWheelScrollView.useDelegate(
childDelegate: ListWheelChildBuilderDelegate(
childCount: listMonths.length,
builder: (BuildContext context, int index) {
if (index < 0 || index > listMonths.length) {
return null;
}
return Container(
decoration: BoxDecoration(
border: Border(
top: BorderSide(color: Colors.green,width: 1),
)
),
child: ListTile(
title: Text(listMonths[index],style: TextStyle(fontSize: 20)),
),
);
}),
useMagnifier: true,
magnification: 1.2,
diameterRatio: 3,
itemExtent: 50,
onSelectedItemChanged: (index){
setState(() {
selectedmonth=index;
getDays();
});
},
physics: FixedExtentScrollPhysics(),
),
),
Container(
width: 100,
height: 180,
child: ListWheelScrollView(
useMagnifier: true,
magnification: 1.2,
diameterRatio: 3,
itemExtent: 50,
onSelectedItemChanged: (index){
},
physics: FixedExtentScrollPhysics(),
children: [
getWeekDay("2020"),
getWeekDay("2021"),
getWeekDay("2022"),
getWeekDay("2023"),
getWeekDay("2024"),
getWeekDay("2025"),
],
),
)
],
),
),
),
),
),
|
Magnifier Property
We can have magnifier for the center item by setting useMagnifier
property to true
. To set the zoom-in rate, use magnification
property which defaults to 1.0. If the value is greater than 1.0, it will look bigger. Setting the value to be lower than 1.0 makes the magnified item looks smaller
ListWheelScrollView( |
Diameter Ratio
The diameter of the cylinder can be set using diameterRatio
property value. The default value is 2.
ListWheelScrollView( |
Setting Controller
The controller used is typically a FixedExtentScrollController
. It will be used if you don't set the controller
property. Be careful if you change it to ScrollController
as it will cause onSelectedItemChanged
not working as it doesn't provide FixedExtentMetrics
Complete code for above screenshot
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_provider/listwheel/country_model.dart';
class ListWheelScroll extends StatefulWidget{
@override
_ListWheelScrollState createState() => _ListWheelScrollState();
}
class _ListWheelScrollState extends State<ListWheelScroll> {
List<CountryModel>listCountry;
List<String>listMonths;
List<int>days;
int selectedmonth=1;
@override
void initState() {
// TODO: implement initState
super.initState();
listCountry=List();
listMonths=List();
days=List();
loadData(context);
getMonths();
getDays();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(title: Text("ListWheelScroll"),backgroundColor: Colors.green,),
body: SingleChildScrollView(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
elevation: 4,
color: Colors.grey,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Container(
color: Colors.white,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Container(
width: 50,
height: 100,
child: ListWheelScrollView.useDelegate(
childDelegate: ListWheelChildBuilderDelegate(
childCount: days.length,
builder: (BuildContext context, int index) {
if (index < 0 || index > days.length) {
return null;
}
return Container(
decoration: BoxDecoration(
border: Border(
top: BorderSide(color: Colors.green,width: 1),
)
),
child: ListTile(
title: Text(days[index].toString(),style: TextStyle(fontSize: 20)),
),
);
}),
useMagnifier: true,
magnification: 1.2,
diameterRatio: 3,
itemExtent: 50,
onSelectedItemChanged: (index){
},
physics: FixedExtentScrollPhysics(),
),
),
Container(
width: 100,
height: 180,
child: ListWheelScrollView.useDelegate(
childDelegate: ListWheelChildBuilderDelegate(
childCount: listMonths.length,
builder: (BuildContext context, int index) {
if (index < 0 || index > listMonths.length) {
return null;
}
return Container(
decoration: BoxDecoration(
border: Border(
top: BorderSide(color: Colors.green,width: 1),
)
),
child: ListTile(
title: Text(listMonths[index],style: TextStyle(fontSize: 20)),
),
);
}),
useMagnifier: true,
magnification: 1.2,
diameterRatio: 3,
itemExtent: 50,
onSelectedItemChanged: (index){
setState(() {
selectedmonth=index;
getDays();
});
},
physics: FixedExtentScrollPhysics(),
),
),
Container(
width: 100,
height: 180,
child: ListWheelScrollView(
useMagnifier: true,
magnification: 1.2,
diameterRatio: 3,
itemExtent: 50,
onSelectedItemChanged: (index){
},
physics: FixedExtentScrollPhysics(),
children: [
getWeekDay("2020"),
getWeekDay("2021"),
getWeekDay("2022"),
getWeekDay("2023"),
getWeekDay("2024"),
getWeekDay("2025"),
],
),
)
],
),
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
elevation: 4,
color: Colors.grey,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Container(
color: Colors.white,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text("Country",style: TextStyle(color: Colors.green,fontWeight: FontWeight.bold,fontSize: 20),),
Container(
width: 200,
height: 180,
child: ListWheelScrollView(
useMagnifier: true,
magnification: 1.2,
diameterRatio: 3,
itemExtent: 50,
onSelectedItemChanged: (index){
print("Selected Country ${listCountry[index].name}");
},
physics: FixedExtentScrollPhysics(),
children: getChildItems(),
),
)
],
),
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
elevation: 4,
color: Colors.grey,
child: Padding(
padding: const EdgeInsets.all(4.0),
child: Container(
color: Colors.white,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text("Day of Week",style: TextStyle(color: Colors.green,fontWeight: FontWeight.bold,fontSize: 20),),
Container(
width: 200,
height: 180,
child: ListWheelScrollView(
useMagnifier: true,
magnification: 1.2,
diameterRatio: 3,
itemExtent: 50,
onSelectedItemChanged: (index){
},
physics: FixedExtentScrollPhysics(),
children: [
getWeekDay("Sunday"),
getWeekDay("Monday"),
getWeekDay("Tuesday"),
getWeekDay("Wednesday"),
getWeekDay("Thursday"),
getWeekDay("Friday"),
getWeekDay("Sateday")
],
),
)
],
),
),
),
),
),
],
),
),
);
}
getChildItems()
{
List<Widget>listWidgets=List();
for(var k=0;k<listCountry.length;k++)
{
listWidgets.add(Container(
decoration: BoxDecoration(
border: Border(
top: BorderSide(color: Colors.green,width: 1),
)
),
child: ListTile(
leading:Image.asset("images/"+listCountry[k].flag,height: 40,width: 40,),
title: Text(listCountry[k].name,style: TextStyle(fontSize: 20)),
),
), );
print("Count ${listCountry[k].flag}");
}
return listWidgets;
}
loadData(context) async
{
await DefaultAssetBundle.of(context).loadString("assets/CountryJson.json")
.then((s) {
setState(() {
var response = json.decode(s);
for (var k = 0; k < response.length; k++) {
listCountry.add(CountryModel.fromJson( response[k]));
}
getChildItems();
});
}).catchError((error) {
print(error);
});
}
getWeekDay(day)
{
return Container(
decoration: BoxDecoration(
border: Border(
top: BorderSide(color: Colors.green,width: 1),
)
),
child: ListTile(
title: Text(day,textAlign: TextAlign.center,style: TextStyle(fontSize: 20),),
),
);
}
getDays()
{
days.clear();
switch(selectedmonth)
{
case 0:
for(int k=0;k<31;k++)
days.add(k+1);
break;
case 1:
for(int k=0;k<28;k++)
days.add(k+1);
break;
case 2:
for(int k=0;k<31;k++)
days.add(k+1);
break;
case 3:
for(int k=0;k<30;k++)
days.add(k+1);
break;
case 4:
for(int k=0;k<31;k++)
days.add(k+1);
break;
case 5:
for(int k=0;k<31;k++)
days.add(k+1);
break;
case 6:
for(int k=0;k<30;k++)
days.add(k+1);
break;
case 7:
for(int k=0;k<31;k++)
days.add(k+1);
break;
case 8:
for(int k=0;k<30;k++)
days.add(k+1);
break;
case 9:
for(int k=0;k<31;k++)
days.add(k+1);
break;
case 10:
for(int k=0;k<30;k++)
days.add(k+1);
break;
case 11:
for(int k=0;k<31;k++)
days.add(k+1);
break;
}
return days;
}
getMonths()
{
listMonths.add("Jan");
listMonths.add("Feb");
listMonths.add("Mar");
listMonths.add("Apr");
listMonths.add("May");
listMonths.add("Jun");
listMonths.add("July");
listMonths.add("Aug");
listMonths.add("Sept");
listMonths.add("Oct");
listMonths.add("Nov");
listMonths.add("Dec");
}
}
|
ListWheelScrollView
Properties
Key key
: The widget key, used to control if it's should be replaced.ScrollController controller
: Used to control the current item, typically aFixedExtentScrollController
, which will be used if none is provided. Changing it toScrollController
will causeonSelectedItemChanged
not working as it doesn't provideFixedExtentMetrics
.ScrollPhysics physics
: How the scroll view should respond to user input. By default it uses platform conventions.diameterRatio
: Ratio of the wheel diameter compared to the size of the viewport.double perspective
: Perspective of the cylindrical projection.double offAxisFraction
: How much the wheel is horizontally off-center, as a fraction of its width. Defaults to 0.0bool useMagnifier
: Whether to use magnifier for the current item. Defaults tofalse
.double magnification
: The zoom-in rate if magnifier is used.double itemExtent*
: Size of each child in the main axis.double squeeze
: The angular compactness of the items in the wheel.onSelectedItemChanged
: Listener that will be called whenever the center item changes.clipToSize
: Whether to clip painted children to the inside of this viewport.renderChildrenOutsideViewport
: Whether to paint children inside the viewport only. Defaults tofalse
.List<Widget>
: List ofWidget
s to be set as the items ofListWheelScrollView
..ListWheelChildDelegate childDelegate
*: A delegate that helps lazily instantiating child
Tags: WheelView, ListView, Flutter UI
Article Contributed By :
|
|
|
|
3301 Views |