Reputation: 463
I want to insert a Icon/Action based on X Y percent position of image as follows:
This is Json file:
[
{
"seasonName": "Spring",
"isDaySelected": true,
"listButton": "Sky",
"pointXPercent": 66.0,
"pointYPercent": 12.0,
"pointName": "Bird",
"pointDialog": "this is a bird"
},
{
"seasonName": "Spring",
"isDaySelected": true,
"listButton": "Sky",
"pointXPercent": 53.6,
"pointYPercent": 27.4,
"pointName": "Cloud",
"pointDialog": "this is a cloud"
},
{
"seasonName": "Spring",
"isDaySelected": true,
"listButton": "Land",
"pointXPercent": 38.5,
"pointYPercent": 78.3,
"pointName": "Flower",
"pointDialog": "this is a flower"
},
{
"seasonName": "Spring",
"isDaySelected": false,
"listButton": "Land",
"pointXPercent": 55.3,
"pointYPercent": 79.8,
"pointName": "Meadow",
"pointDialog": "this is a meadow"
},
{
"seasonName": "Summer",
"isDaySelected": true,
"listButton": "Sky",
"pointXPercent": 38.9,
"pointYPercent": 23.5,
"pointName": "Sun",
"pointDialog": "this is the sun"
}
]
I want that when click on the TogglesButton
"Sky" => get data from Json:
Get values seasonName = "Spring" (because TabBar
is being
selected as "Spring")
Get values that satisfy (1) and have isDaySelected = "true" (because the TogglesButton
isDaySelected is being selected as true)
Get values that satisfy (1) and (2) and listButton = "Sky"
Show the pointName values that satisfy (1) (2) (3) on image based on X Y percent. Ex:
pointName: "Bird" => pointXPercent = 66.0, pointYPercent = 12.0
pointName: "Cloud" => pointXPercent = 53.6, pointYPercent = 27.4
So pls help me, this is main file:
import 'package:ask/model/season_model.dart';
import 'package:ask/services/season_service.dart';
import 'package:flutter/material.dart';
class SeasonPage extends StatefulWidget {
SeasonPage() : super();
@override
_SeasonPageState createState() => _SeasonPageState();
}
class _SeasonPageState extends State<SeasonPage> {
List<Season> _season = [];
List<bool> isDaySelected = [true, false];
List<bool> listButton = [false, false, false];
final String springDay = 'https://i.imgur.com/MUuCuYI.png';
final String springNight = 'https://i.imgur.com/QxbAg8Y.png';
final String summerDay = 'https://i.imgur.com/9Qi6oLm.png';
final String summerNight = 'https://i.imgur.com/jrFGHvn.png';
final String autumnDay = 'https://i.imgur.com/yo0RWi6.png';
final String autumnNight = 'https://i.imgur.com/iPW4r2g.png';
final String winterDay = 'https://i.imgur.com/CnFDmEJ.png';
final String winterNight = 'https://i.imgur.com/lFNdvDe.png';
@override
void initState() {
super.initState();
SeasonServices.getSeason().then((seasons) {
setState(() {
_season = seasons;
});
});
}
@override
Widget build(BuildContext context) {
return Container(
child: DefaultTabController(
length: 4,
child: Scaffold(
appBar: AppBar(
title: Text('Season'),
bottom: TabBar(tabs: [
Tab(child: Text('Spring')),
Tab(child: Text('Summer')),
Tab(child: Text('Autumn')),
Tab(child: Text('Winter')),
]),
),
body: Column(children: [
Center(
child: ToggleButtons(
children: [Text('Day'), Text('Night')],
onPressed: (int index) {
setState(() {
for (int buttonIndex = 0; buttonIndex < isDaySelected.length; buttonIndex++) {
if (buttonIndex == index) {
isDaySelected[buttonIndex] = true;
} else {
isDaySelected[buttonIndex] = false;
}
}
});
},
isSelected: isDaySelected)),
SizedBox(height: 5),
Center(
child: ToggleButtons(
children: [Text('Sky'), Text('Mountain'), Text('Land')],
onPressed: (int index) {
setState(() {
for (int buttonIndex = 0; buttonIndex < listButton.length; buttonIndex++) {
if (buttonIndex == index) {
listButton[buttonIndex] = !listButton[buttonIndex];
} else {
listButton[buttonIndex] = false;
}
}
});
},
isSelected: listButton)),
Expanded(
child: TabBarView(children: [
isDaySelected[0] ? Image.network(springDay) : Image.network(springNight),
isDaySelected[0] ? Image.network(summerDay) : Image.network(summerNight),
isDaySelected[0] ? Image.network(autumnDay) : Image.network(autumnNight),
isDaySelected[0] ? Image.network(winterDay) : Image.network(winterNight),
]),
)
]))));
}
}
Upvotes: 2
Views: 1724
Reputation: 1791
There are several ways to achive result
Use Stack and wrap it in IntrinsicHeight to set it height as you image height
Column(
children: <Widget>[
IntrinsicHeight(
child: Stack(
children: <Widget>[
Image.network('https://i.imgur.com/MUuCuYI.png'),
Align(
alignment: Alignment(.66 * 2 - 1, .12 * 2 - 1),
child: Text('bird'),
),
Align(
alignment: Alignment(.536 * 2 - 1, .274 * 2 - 1),
child: Text('cloud'),
),
],
),
),
],
),
This will be sized to Stack children max height and until network image loaded(finally you know size) it will be tall as max of bird or cloud heigh
Note that IntrinsicHeight
is relatively expensive. Avoid using it where possible.
For more complex cases you can use LayoutBuilder
body: Column(
children: <Widget>[
Expanded(
child: LayoutBuilder(
builder: (context, constraints) {
return Stack(
children: <Widget>[
Positioned(
top: .12 * constraints.biggest.height,
left: .66 * constraints.biggest.width,
child: Text('bird'),
),
Positioned(
top: .274 * constraints.biggest.height,
left: .536 * constraints.biggest.width,
child: Text('cloud'),
),
],
);
},
),
),
],
),
PS Here we laying out by left&top of our bird&cloud If you need to layout by center of birs&cloud - you have to know their sizes and do a little bit more math
Upvotes: 2
Reputation: 8290
You can use Align to choose the position in a stack like this:
Stack(children: [
child: Align(
alignment: Alignment(-.40, -.90),
child: MyPictureWidget()
),
]);
Nicer because you don't need to get the constraints. :) Alignment(0, 0)
would be at the center
Upvotes: 0