How would I create a circular ListView in Flutter? I want something that allows me to have a list of widgets rotate around an origin.
Something similar to this:
Any help would be appreciated.
Circular List View Demo. Which Is helpful for You May be.
Main.dart
import 'package:master/numbers_list.dart';
import 'package:master/radial_list.dart';
import 'package:meta/meta.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyHomePage());
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: new ThemeData(
accentColor: Colors.blue,
),
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
RadialListViewModel radialList;
HomePage({
@required this.radialList
});
@override
HomePageState createState() {
return new HomePageState();
}
}
class HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(
title: Text("My Home Page"),
),
body: Stack(
children: <Widget>[
RadialList(
radialList: radialNumbers,
radius: 150.00,
),
],
)
);
}
}
numbers_list.dart
import 'package:master/radial_list.dart';
final RadialListViewModel radialNumbers = new RadialListViewModel(
items: [
new RadialListItemViewModel(
number: 1,
isSelected: true,
),
new RadialListItemViewModel(
number: 2,
isSelected: false,
),
new RadialListItemViewModel(
number: 3,
isSelected: false,
),new RadialListItemViewModel(
number: 4,
isSelected: false,
),
new RadialListItemViewModel(
number: 5,
isSelected: false,
),
new RadialListItemViewModel(
number: 6,
isSelected: false,
),
new RadialListItemViewModel(
number: 7,
isSelected: false,
),
new RadialListItemViewModel(
number: 8,
isSelected: false,
),
new RadialListItemViewModel(
number: 9,
isSelected: false,
),
new RadialListItemViewModel(
number: 10,
isSelected: false,
),
new RadialListItemViewModel(
number: 11,
isSelected: false,
),new RadialListItemViewModel(
number: 12,
isSelected: false,
),
]
);
radial_list.dart
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:master/radial_position.dart';
class RadialList extends StatefulWidget {
final RadialListViewModel radialList;
final double radius;
RadialList({
this.radialList,
this.radius,
});
List<Widget> _radialListItems(){
final double firstItemAngle = pi;
final double lastItemAngle = pi;
final double angleDiff = (firstItemAngle + lastItemAngle) / (radialList.items.length);
double currentAngle = firstItemAngle;
return radialList.items.map((RadialListItemViewModel viewModel){
final listItem = _radialListItem(viewModel,currentAngle);
currentAngle += angleDiff;
return listItem;
}).toList();
}
Widget _radialListItem(RadialListItemViewModel viewModel, double angle){
return Transform(
transform: new Matrix4.translationValues(
180.0,
250.0,
0.0
),
child: RadialPosition(
radius: radius,
angle: angle,
child: new RadialListItem(
listItem: viewModel,
),
),
);
}
@override
RadialListState createState() {
return new RadialListState();
}
}
class RadialListState extends State<RadialList> {
@override
Widget build(BuildContext context) {
return new Stack(
children: widget._radialListItems(),
);
}
}
class RadialListItem extends StatefulWidget {
final RadialListItemViewModel listItem;
RadialListItem({
this.listItem
});
@override
RadialListItemState createState() {
return new RadialListItemState();
}
}
class RadialListItemState extends State<RadialListItem> {
@override
Widget build(BuildContext context) {
return Transform(
transform: new Matrix4.translationValues(-30.0, -30.0, 0.0),
child: Container(
width: 60.0,
height: 60.0,
decoration: new BoxDecoration(
shape: BoxShape.circle,
color: Colors.deepPurpleAccent,
border: new Border.all(
color: Colors.red,
width: 2.0
)
),
child: Padding(
padding: const EdgeInsets.all(0.0),
child: OutlineButton(
shape: new RoundedRectangleBorder(borderRadius: new BorderRadius.circular(60.0)),
color: Colors.transparent,
onPressed: () {
setState(() {
widget.listItem.isSelected = true;
//widget.listItem.number = widget.listItem.number + 1;
});
},
child: new Text(
widget.listItem.number.toString(),
style: new TextStyle(
color: widget.listItem.isSelected ? Colors.red : Colors.yellow,
fontSize: 20.0
),
),
),
),
),
);
}
}
class RadialListViewModel{
final List<RadialListItemViewModel> items;
RadialListViewModel({
this.items = const [],
});
}
class RadialListItemViewModel{
int number;
bool isSelected;
RadialListItemViewModel({
this.isSelected=false,
this.number,
});
}
radial_position.dart
import 'package:flutter/material.dart';
import 'dart:math';
class RadialPosition extends StatefulWidget {
final double radius;
final double angle;
final Widget child;
RadialPosition({
this.angle,
this.child,
this.radius,
});
@override
RadialPositionState createState() {
return new RadialPositionState();
}
}
class RadialPositionState extends State<RadialPosition> {
@override
Widget build(BuildContext context) {
final x = cos(widget.angle) * widget.radius;
final y = sin(widget.angle) * widget.radius;
return Transform(
transform: new Matrix4.translationValues(x, y, 0.0),
child: widget.child,
);
}
}
A simpler way to do it is to use this package circular_motion
Here's an example using that package
CircularMotion.builder(
itemCount: 18,
centerWidget: Text('Center'),
builder: (context, index) {
return Text('$index');
}
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With