Stack Alignment for an indeterminate number of children - flutter

I am building an app in flutter and part of what I am doing is fetching a list of actions from a server then building buttons for each action. I am trying to display the buttons in a circle and generate a list of raised button widgets. I am then trying to use a Stack to lay out this list in a circle, but cannot figure out how to use positioning to position objects in a circle when I do not know how many objects I will have (I know it will be in a range of about 3-15).
Here is the build method for my stack. Assume all methods and lists and variables are defined correctly and work. I am just concerned about the alignment
#override
Widget build(BuildContext context) {
List<Widget> actions = [];
for(var action in widget.actionsList){
actions.add(RaisedButton(
onPressed: () => _handleAction(action[0]),
shape: CircleBorder(),
child: Text(action[1] + ': ' + action[2]),
));
}
return Scaffold(
body: Center(
child: Stack(
children: actions,
alignment: //HELP,
),
),
);
}
If you have any ideas about how to do the alignment or another way to go about this to make a circle of buttons please let me know. I really want to make a circle, but am not wedded to it impossible (which I doubt) or super convoluted.
Thanks!

Here's how I would do it.
TL;DR;
final actionsList = [
"one",
"two",
"three",
"four",
"five",
];
#override
Widget build(BuildContext context) {
return Scaffold(
body: LayoutBuilder(
builder: (context, constraints) => Stack(
children: layedOutButtons(
centerOfCircle:
Offset(constraints.maxWidth, constraints.maxHeight) / 2,
circleRadius: 100,
),
),
),
);
}
Offset getCoordinateFromAngle({double radius, double angle}) => Offset(
radius * sin(angle),
radius * cos(angle),
);
List<Widget> layedOutButtons({
Offset centerOfCircle,
double circleRadius,
}) {
var buttonRadius = 25.0;
var dispatchAngle = pi * 2 / actionsList.length;
List<Widget> widgets = [];
var i = 0;
for (var action in actionsList) {
var position = getCoordinateFromAngle(
radius: circleRadius,
angle: dispatchAngle * i++,
);
widgets.add(
Positioned(
top: centerOfCircle.dy - position.dy - buttonRadius,
left: centerOfCircle.dx + position.dx - buttonRadius,
width: buttonRadius * 2,
height: buttonRadius * 2,
child: FloatingActionButton(
child: Text(action),
onPressed: () {},
),
),
);
}
return widgets;
}
Explanation
If you want to dispatch a number of widgets on a circle, you have to:
define centerOfCircle, the position of the center of that circle. To do so, I use the LayoutBuilder widget to get the constraints of the layout and determine the center of the Stack => (width / 2, height / 2).
define circleRadius, the radius of that circle (in my example: 100)
Give those data to layedOutButtons that will dispatch widgets on the circle with the Positioned widget.
Widget build(BuildContext context) {
return Scaffold(
body: LayoutBuilder(
builder: (context, constraints) => Stack(
children: layedOutButtons(
centerOfCircle: Offset(constraints.maxWidth, constraints.maxHeight) / 2,
circleRadius: 100,
),
),
),
);
}
List<Widget> layedOutButtons({
Offset centerOfCircle,
double circleRadius,
}) {
List<Widget> widgets = [];
for (var action in actionsList) {
widgets.add(
Positioned(
child: FloatingActionButton(
child: Text(action),
onPressed: () {},
),
),
);
}
return widgets;
}
Now, you need to define how you will dispatch the widgets on the circle, based on their number. e.g, it there's 2 widgets, dispatch them at 180° from each other (meaning one on the top of the circle, one on the bottom. If there's 4, dispatch at 90° from each other, etc. Note that it is expressed in radians (not in degrees).
var dispatchAngle = pi * 2 / actionsList.length;
Then you have to define the coordinates (x, y) of a point on a circle based on an angle (look at this).
Offset getCoordinateFromAngle({double radius, double angle}) => Offset(
radius * sin(angle),
radius * cos(angle),
);
Use that to fill the top and left attributes of the Positioned widget.
List<Widget> layedOutButtons({
Offset centerOfCircle,
double circleRadius,
}) {
var dispatchAngle = pi * 2 / actionsList.length;
List<Widget> widgets = [];
var i = 0;
for (var action in actionsList) {
var position = getCoordinateFromAngle(
radius: circleRadius,
angle: dispatchAngle * i++, //increment angle for each widget
);
widgets.add(
Positioned(
top: centerOfCircle.dy - position.dy, //something's wrong here
left: centerOfCircle.dx + position.dx, //something's wrong here
child: FloatingActionButton(
child: Text(action),
onPressed: () {},
),
),
);
}
return widgets;
}
Now everything is almost ready except that there's a misalignement. It's due to the fact that the widgets are positioned based on their top left corners. We want to refine the positioning so it match the center of our widgets.
var buttonRadius = 25.0;
Positioned(
top: centerOfCircle.dy - position.dy - buttonRadius,
left: centerOfCircle.dx + position.dx - buttonRadius,
width: buttonRadius * 2,
height: buttonRadius * 2,
child: FloatingActionButton(
child: Text(action),
onPressed: () {},
),
),

Related

How to create dotted border around circular avatar in flutter

I'd like to display Instagram-like stories on my Flutter app and want to show the number of stories a user has uploaded by using borders around the user's avatar.
Say a user has uploaded 3 stories, i'll show 3 rounded border lines around the avatar image separated by equal number of spaces & if a user uploads 80 stories, i'll show 80 tiny round border lines separated by equal number of spaces.
I tried using plugins from pub.dev for this, like
dotted_border 2.0.0+2
fdottedline 1.0.1
just to name a few, but i can't seem to get an accurate count of spaces & dashes to fulfill the requirements above.
Below is an example:
FDottedLine(
color: Colors.black,
strokeWidth: 2.0,
dottedLength: 30,
space: 4,
corner: FDottedLineCorner.all(100.0),
child: Padding(
padding: const EdgeInsets.all(3.0),
child: SizedBox.square(
dimension: 0.055.h,
child: ClipRRect(
borderRadius: BorderRadius.circular(100),
child: ImageBox.network(
photo: user.photo.getOrEmpty,
elevation: 2,
replacement: Image.asset(AppAssets.defaultUserImage(user.gender.getOrNull)),
borderRadius: BorderRadius.circular(100),
),
),
),
),
),
No matter how i tweak the dottedLength & space params, i can't get equal number of spaces nor dashes.
I also tried using Path(), CustomPainter() but i barely know much about how to use it.
Any idea how i can achieve this using either CustomPainter() or a plugin?
Thanks for posting all your tries as it made me jump to CustomPaint directly to try
the approach that (could) work (but not tested well) is drawArc
the logic is simply to draw an arc based on the number of stories and start the next arc after leaving some space
the below code is looping for the number of stories to draw every story arc and start the next story arc (if stories > 1) after adding some value (the space between the stories) to the start of the next arc location (on the circle).
for(int i =0;i<numberOfStories;i++){
canvas.drawArc(
rect,
inRads(startOfArcInDegree),
inRads(arcLength),
false,
Paint()
..color = i==0||i==1?Colors.grey:Colors.teal
..strokeWidth =14.0
..style = PaintingStyle.stroke
);
startOfArcInDegree += arcLength + spaceLength;
}
full code with detailed explanation:
import 'dart:math';
import 'package:flutter/material.dart';
class DottedBorder extends CustomPainter {
//number of stories
final int numberOfStories;
//length of the space arc (empty one)
final int spaceLength;
//start of the arc painting in degree(0-360)
double startOfArcInDegree = 0;
DottedBorder({required this.numberOfStories, this.spaceLength = 10});
//drawArc deals with rads, easier for me to use degrees
//so this takes a degree and change it to rad
double inRads(double degree){
return (degree * pi)/180;
}
#override
bool shouldRepaint(DottedBorder oldDelegate) {
return true;
}
#override
void paint(Canvas canvas, Size size) {
//circle angle is 360, remove all space arcs between the main story arc (the number of spaces(stories) times the space length
//then subtract the number from 360 to get ALL arcs length
//then divide the ALL arcs length by number of Arc (number of stories) to get the exact length of one arc
double arcLength = (360 - (numberOfStories * spaceLength))/numberOfStories;
//be careful here when arc is a negative number
//that happens when the number of spaces is more than 360
//feel free to use what logic you want to take care of that
//note that numberOfStories should be limited too here
if(arcLength<=0){
arcLength = 360/spaceLength -1;
}
Rect rect = Rect.fromLTWH(0, 0, size.width, size.height);
//looping for number of stories to draw every story arc
for(int i =0;i<numberOfStories;i++){
//printing the arc
canvas.drawArc(
rect,
inRads(startOfArcInDegree),
//be careful here is: "double sweepAngle", not "end"
inRads(arcLength),
false,
Paint()
//here you can compare your SEEN story index with the arc index to make it grey
..color = i==0||i==1?Colors.grey:Colors.teal
..strokeWidth =14.0
..style = PaintingStyle.stroke
);
//the logic of spaces between the arcs is to start the next arc after jumping the length of space
startOfArcInDegree += arcLength + spaceLength;
}
}
}
class DottedBorderExample extends StatelessWidget {
const DottedBorderExample({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Arcs etc')),
body:Center(
child: Stack(
alignment: Alignment.center,
children: [
SizedBox(
width: 300,height: 300,
child: CustomPaint(
painter: DottedBorder(numberOfStories: 13,spaceLength:4 ),
),),
Container(child:const Center(child: Text("Some Image",style: TextStyle(fontSize: 18,color: Colors.black),)),width: 270,height: 270,decoration: const BoxDecoration(color: Colors.purple,shape: BoxShape.circle),)
],
),
),
);
}
}
void main() {
runApp(
const MaterialApp(
home: DottedBorderExample(),
),
);
}
click to look at images:
we should determine 2 things
color width
separation width\
color width can be measured through below function
double colorWidth(double radius, int statusCount, double separation)
{
return ((2 * pi * radius) - (statusCount * separation)) / statusCount;
}
2 * PI * radius >> Circumference of a circle
SO >> Circumference minus total separation pixels needed, Then result divided by total status count.
now we have the width of each status equally, To fit the circle border
measuring separation pixels width
depending on the status number to be more enhanced as WhatsApp
double separation(int statusCount) {
if (statusCount <= 20)
return 3.0;
else if (statusCount <= 30)
return 1.8;
else if (statusCount <= 60)
return 1.0;
else
return 0.3;
}
Now we add the dotted_border package to our project and import it
https://pub.dev/packages/dotted_border
import 'package:dotted_border/dotted_border.dart';
assuming we have some declarations above they are:
//each digit express a status number
List status = [1, 2, 5, 4, 9, 13, 15, 20, 30, 40, 80];
//circle radius
double radius = 27.0;
dashPattern:
we have two states
one status or more than one (multiple statuses)
dashPattern: status[index] == 1
? [
//one status
(2 * pi * (radius + 2)), // take all border
0, //zere separators
]
: [
//multiple status
colorWidth(radius + 2, status[index],
separation(status[index])),
separation(status[index]),
],
FULL CODE:
import 'dart:math';
import 'package:dotted_border/dotted_border.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'STATUS',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
List status = [1, 2, 5, 4, 9, 13, 15, 20, 30, 40, 80];
double radius = 27.0;
double colorWidth(double radius, int statusCount, double separation) {
return ((2 * pi * radius) - (statusCount * separation)) / statusCount;
}
double separation(int statusCount) {
if (statusCount <= 20)
return 3.0;
else if (statusCount <= 30)
return 1.8;
else if (statusCount <= 60)
return 1.0;
else
return 0.3;
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: ListView.separated(
itemCount: status.length,
separatorBuilder: (context, index) => Divider(
color: Colors.black,
height: 15,
),
itemBuilder: ((context, index) => Row(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child:
/// Creating a circle with a dotted border.
DottedBorder(
color: Colors.teal.shade300,
borderType: BorderType.Circle,
radius: Radius.circular(radius),
dashPattern: status[index] == 1
? [
//one status
(2 * pi * (radius + 2)),
0,
]
: [
//multiple status
colorWidth(radius + 2, status[index],
separation(status[index])),
separation(status[index]),
],
strokeWidth: 3,
child: CircleAvatar(
radius: radius,
backgroundColor: Colors.transparent,
child: CircleAvatar(
radius: radius - 2,
),
),
),
),
SizedBox(
width: 10,
),
Text(
'${status[index]}',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
],
)),
),
),
);
}
}
You can use a package named status_view:
Link:
status_view
Usage from official docs
StatusView(
radius: 40,
spacing: 15,
strokeWidth: 2,
indexOfSeenStatus: 2,
numberOfStatus: 5,
padding: 4,
centerImageUrl: "https://picsum.photos/200/300",
seenColor: Colors.grey,
unSeenColor: Colors.red,
),

How to get InteractiveViewer image pixel coordinate in flutter?

i want to get pixel coordinate when i tapped the screen, i use interactiveView and GestureDetect in Fultter, i am so confused about the matrix transform , i am new to App develop, please give some advice if you could, very appraciate, Below is my code, which now i can zoom the image, but i can't calculate the coorect pixel coordiante when i click the screen. and since i have no idea how to calculate the ratio between pixel distance<->screen distance, i was stucked there. please help me.
What i am doing is i need pick a pixel position from the image, so i need zoom image first to get precise position,that's why i need ineractiveViewer . and at the same time i need record the gesture behavior, to monitor the behavior, then i wrapper InteractiveView to GestureDetect.
it look like this for now:
enter image description here
Widget mapView() {
double offsetX, offsetY;
return Stack(
children: <Widget>[
Positioned.fill(
child:
GestureDetector(
onTapUp: (TapUpDetails details) {
offsetX = details.localPosition.dx;
offsetY = details.localPosition.dy;
// print(
//"tap local pos, X: ${details.localPosition.dx}, Y: ${details.localPosition.dy}");
// print(
// "tap global pos, X: ${details.globalPosition.dx}, Y: ${details.globalPosition.dy}");
_childWasTappedAt = _transformationController!.toScene(details.localPosition);
// print(
// "child pos to scene , X: ${_childWasTappedAt!.dx}, Y: ${_childWasTappedAt!.dy}");
//double origin_scree_pixel_radio = 17;
MediaQueryData queryData;
queryData = MediaQuery.of(context);
double pixel_ratio = queryData.devicePixelRatio;
double scree_pixel_radio = (1.0 / _cur_scale_value!)*pixel_ratio;
double trans_x = -1.0 * _transformationController!.value.getTranslation().x;
double local_offset_x = offsetX;
double pixel_x = trans_x + local_offset_x * scree_pixel_radio;
print("scale: ${_cur_scale_value}");
print("radio: ${pixel_ratio}");
print("view tran x: ${trans_x}");
print("offset x: ${local_offset_x}");
//print("image_Info: ${_image_info.toString()}");
print("Pixel X: ${pixel_x}");
},
child:
InteractiveViewer(
transformationController: _transformationController,
minScale: 0.001,
maxScale: 200.0,
constrained: false,
child: Image.asset(
imagePath,
filterQuality:FilterQuality.high,
),
onInteractionEnd: (ScaleEndDetails details) {
_cur_scale_value = _transformationController!.value.getMaxScaleOnAxis();
//print("current scale: ${_cur_scale_value}");
},
onInteractionUpdate: (ScaleUpdateDetails details){
//print('onInteractionUpdate----' + details.toString());
},
),
),
),
Positioned(
top: 0.0,//_vehicle_y,
left: 0.0,//_vehicle_x,
child: Icon(Icons.favorite, color: Colors.red,),
),
],
);
}
Use this onInteractionUpdate method to get Coordinates. use also use different methods.
Vist This site for more info:-
https://api.flutter.dev/flutter/widgets/InteractiveViewer/onInteractionUpdate.html
https://api.flutter.dev/flutter/gestures/ScaleStartDetails/localFocalPoint.html
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: InteractiveViewer(
onInteractionUpdate: (v) {
print(v.localFocalPoint.dx);
print(v.localFocalPoint.dy);
},
child: Image.network(
"https://images.unsplash.com/photo-1643832678771-fdd9ed7638ae?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHx0b3BpYy1mZWVkfDd8Ym84alFLVGFFMFl8fGVufDB8fHx8&auto=format&fit=crop&w=2400&q=60",
fit: BoxFit.fitHeight,
),
),
),
);
}

Flutter - Rows with Icons like a Bow

in my form I have a Container with some Rows and nested Icons. Every Icon has got a Tap event with a function.
How can I curve all Rows with Icons like this.
to obtain this result as a bow (like rainbow)?
I think there is no shortcut to do this if you want a smooth curve. You must provide some constrains that what the ratio of width and height and calculate the curve formulation. You can try to combine Stack & Align to fullfill your layout.
Here is my assumption from your image:
X axis is separated equally.
Y axis is like a circular sector which radian from 1.25 pi to 1.75 pi (a circle is 2 pi). So the total radian is pi
import 'dart:math';
class CustomRainbow extends StatelessWidget {
#override
Widget build(BuildContext context) {
List<Widget> icons = List<Icon>.filled(14, Icon(Icons.tag_faces));
return Scaffold(
backgroundColor: Colors.black87,
body: Center(
child: Container(
width: 300,
height: 130,
color: Colors.white,
child: Stack(
children: [
..._bridge(icons),
..._bridge(icons, row: 1),
..._bridge(icons, row: 2),
..._bridge(icons, row: 3),
],
),
),
),
);
}
List<Widget> _bridge(List<Widget> icons, {int row = 0}) {
double totalRad = pi;
double rowHeightFactor = 0.4;
int count = icons.length;
double width = 2.0 / (count - 1);
double singleRad = totalRad / (count + 1);
double startRad = pi * 1.5 - totalRad * 0.5;
List<Widget> result = [];
for (int i = 0; i < count; i++) {
result.add(
Align(
alignment: Alignment(
-1 + i * width, sin((startRad + singleRad * (i + 1)))) +
Alignment(0, row * rowHeightFactor),
child: icons[i],
),
);
}
return result;
}
}
You can still tune the Width, Height, totalRad and rowHeightFactor,
Make sure the Alignment value is in range of (-1.0, 1.0) and all the icons will be in the Container.
A hack could be to display row(column) and to add a transparent (default) container with the respective height for each column as the first element, to move the subsequent icons downwards.
One simple way of doing that is to build Columns inside the Row with placeholders that will ocuppy some bottom space to make taller columns:
static const double size = 40.0;
static const placeholderSize = size / 2;
static const int columnsNumber = 8;
Widget repeatedWidget() {
return IconButton(
icon: Icon( //Your icon button
Icons.tag_faces,
size: size,
),
onPressed: () {},
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate( //generating a fixed number of columns with icons for the example
columnsNumber,
(index) {
return Column(
mainAxisAlignment: MainAxisAlignment.end,
children: List.generate(
6,
(index) => repeatedWidget(),
)..add( //adding a widget at the final of each Column
Column(
children: List.generate(
/*if the current index is greater or equal to half of the number
of columns return it minus index - 1, else return the index*/
index >= columnsNumber / 2
? columnsNumber - index - 1
: index,
(index) => Container( //containers that will ocuppy the bottom space of each column
height: placeholderSize,
),
),
),
),
);
},
),
),
);
}
The result:

Flutter : Change size of stack when children overflow

I have a draggable widget (from https://medium.com/flutter-community/create-a-draggable-widget-in-flutter-50b61f12635d ) with a stack in a container (red color) consists of moveable children. Here is the widget tree:
I wanted to add a Gesture Transformations as FormBuilder ( https://github.com/flutter/flutter/blob/master/examples/flutter_gallery/lib/demo/transformations/transformations_demo.dart ) to transform the matrix, as you can see in the GIF, mainly zoom in/out and transform x/y.
class _HomeViewState extends State<HomeView> {
final _stackKey;
_HomeViewState(this._stackKey);
List<Widget> movableItems = [];
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text('SynApp'),
actions: <Widget>[
IconButton(
onPressed: () {
x = 200.0;
y = 200.0;
setState(() {
movableItems.add(
MoveableStackItem(_stackKey),
);
});
},
icon: Icon(Icons.add),
),
],
),
body: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
// Draw the scene as big as is available, but allow the user to
// translate beyond that to a visibleSize that's a bit bigger.
final Size size = Size(constraints.maxWidth, constraints.maxHeight);
final Size visibleSize = Size(size.width * 3, size.height * 2);
return GestureTransformable(
reset: _reset,
onResetEnd: () {
setState(() {
_reset = false;
});
},
child: new Container(
color: Colors.red,
child: Stack(
key: _stackKey,
overflow: Overflow.visible,
fit: StackFit.expand,
children: movableItems),
),
boundaryRect: Rect.fromLTWH(
-visibleSize.width / 2,
-visibleSize.height / 2,
visibleSize.width,
visibleSize.height,
),
initialTranslation: Offset(size.width, size.height),
size: size,
);
}),
);
}
}
The problem is:
a) the size of the stack is equal to the initial screen.
b)when I move items out of the screen, gestureDetection stops, the items are no longer moveable.
What I want:
I want to dynamically resize the size of the stack (the red box) depending on where I move the items.
I was able to find the position and size of the stack widget.
Size stackSize;
Offset stackPosition;
_MoveableStackItemState(this._stackKey);
getSizeAndPosition() {
RenderStack _stackStack = _stackKey.currentContext.findRenderObject();
stackSize = _stackStack.size;
stackPosition = _stackStack.localToGlobal(Offset.zero);
print('stackSize $stackSize');
print('stackPosition $stackPosition');
}
But I'm starting to get lost in advanced UI object orientated stateful widget manipulation.
You can wrap the red stack with an AnimatedContainer.
LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
// Draw the scene as big as is available, but allow the user to
// translate beyond that to a visibleSize that's a bit bigger.
final Size size = Size(constraints.maxWidth, constraints.maxHeight);
final Size visibleSize = Size(size.width * 3, size.height * 2);
return GestureTransformable(
reset: _reset,
onResetEnd: () {
setState(() {
_reset = false;
});
},
child: new AnimatedContainer(
color: Colors.red,
duration: Duration(milliseconds: 200),
width: _stackWidth,
height: _stackHeight,
child: Stack(
key: _stackKey,
overflow: Overflow.visible,
fit: StackFit.expand,
children: movableItems),
),
boundaryRect: Rect.fromLTWH(
-visibleSize.width / 2,
-visibleSize.height / 2,
visibleSize.width,
visibleSize.height,
),
initialTranslation: Offset(size.width, size.height),
size: size,
);
}),
Try to listen the following event of the GestureTransformable
onPanUpdate: (DragUpdateDetails details){
var deltaX = details.delta.dx;
var deltaY = details.delta.dy;
}
DragUpdateDetails object let you to know the delta
the amount the pointer has moved in the coordinate space of the event
receiver since the previous update
on the x and y axis.
Inside the "onPanUpdate" you can update the width and the height of the animated container related to the delta of the gesture.
setState((){
_stackHeight = /* ... */
_stackWidth = /* ... */
});

Trying to push to different viewControllers/view based on what button is pressed

I am new to Flutter and am struggling with what seems to be a simple thing.
I have a few buttons in my view, each corresponding to a different (view controller) widget. Depending on what button is pressed I would like to navigate to the corresponding view.
Please see below for a better explanation.
Future navigateToPage(context, vc) async {
Navigator.push(context, MaterialPageRoute(builder: (context) => vc()));
}
class CircularView extends StatelessWidget {
#override
Widget build(BuildContext context) {
StatelessWidget vc;
double width = MediaQuery.of(context).size.width;
double height = MediaQuery.of(context).size.height;
Widget bigCircle = Container(
width: (width * 0.9),
height: (height * 0.5),
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
);
return Material(
color: Colors.white,
child: Center(
child: Stack(
children: <Widget>[
bigCircle,
Positioned(
child: CustomFloatingActionButton(
onPressed: () {
vc = MoneyView(); // < -- Here is where I am assigning the vc variable to a view.
navigateToPage(context, vc);
},
buttonType: ButtonType.money,
buttonImage: FontAwesomeIcons.moneyBill,
label: '',
),
top: ((height * 0.5) * 0.175),
left: ((width * 0.9) * 0.12),
),
Positioned(
child: CustomFloatingActionButton(
onPressed: () {
vc = SchedulesView(); // < ---- And here
navigateToPage(context, vc);
},
buttonType: ButtonType.schedules,
buttonImage: FontAwesomeIcons.database,
label: '',
),
top: ((height * 0.5) * 0.123),
left: ((width * 0.9) * 0.559),
),
Positioned(
child: CustomFloatingActionButton(
onPressed: () {
vc = VisitsView; // < ---- And here
navigateToPage(context, vc);
},
buttonType: ButtonType.keyDates,
buttonImage: FontAwesomeIcons.calendar,
label: '',
),
top: ((height * 0.5) * 0.434),
left: ((width * 0.9) * 0.729),
),
Positioned(
child: CustomFloatingActionButton(
onPressed: () {
vc = RequestsView(); // < ---- And here
navigateToPage(context, vc);
},
buttonType: ButtonType.requests,
buttonImage: FontAwesomeIcons.question,
label: '',
),
top: ((height * 0.5) * 0.687),
left: ((width * 0.76) * 0.53),
),
Positioned(
child: CustomFloatingActionButton(
onPressed: () {
vc = KeyDatesView(); // < ---- And here
navigateToPage(context, vc);
},
buttonType: ButtonType.visits,
buttonImage: FontAwesomeIcons.handshake,
label: '',
),
top: ((height * 0.5) * 0.53),
left: ((width * 0.76) * 0.051),
),
],
),
),
);
}
}
The error I am receiving on the simulator states that the No such method error: 'MoneyView' has no instance method 'call'.
So perhaps I am doing something wrong in the 'MoneyView' class.
Thanks for any help you can offer.
Add the constructor to the VisitsView object.
Actually don't call the constructor of vc object in the lambda of the navigateToPage method, cause when you use this function you pass the object inside the function. This is already created object, it doesn't need a constructor.
As advice you can use the named params in your method and functions. It will simplify your life in the future :)