【问题标题】:Flutter: How to insert Icon/Action based on X Y percent position of imageFlutter:如何根据图像的 X Y 百分比位置插入图标/动作
【发布时间】:2020-06-20 15:58:32
【问题描述】:

我想根据图像的 X Y 百分比位置插入一个图标/动作,如下所示:

这是 Json 文件:

[
  {
    "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"
  }
]

我希望当点击TogglesButton“Sky”=> 从 Json 中获取数据:

  1. 获取值 seasonName = "Spring"(因为 TabBar 正在 选为“弹簧”)

  2. 获取满足 (1) 并具有 isDaySelected = "true" 的值(因为 TogglesButton isDaySelected 被选择为 true)

  3. 获取满足 (1) 和 (2) 和 listButton = "Sky"

    的值
  4. 根据 X Y 百分比在图像上显示满足 (1) (2) (3) 的 pointName 值。例如:

  • pointName: "Bird" => pointXPercent = 66.0, pointYPercent = 12.0

  • pointName: "Cloud" => pointXPercent = 53.6, pointYPercent = 27.4

所以请帮帮我,这是主文件:

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),
                    ]),
                  )
                ]))));
  }
}

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    有几种方法可以获得结果

    使用 Stack 并将其包装在 IntrinsicHeight 中以将其高度设置为图像高度

          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'),
                    ),
                  ],
                ),
              ),
            ],
          ),
    

    这将被调整为 Stack children 的最大高度,直到加载网络图像(最后你知道大小)它会像鸟或云的最大高度一样高

    请注意,IntrinsicHeight 相对昂贵。尽可能避免使用它。

    对于更复杂的情况,您可以使用 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 在这里,我们在鸟和云的左侧和顶部布置 如果你需要按 birs&cloud 的中心进行布局 - 你必须知道它们的大小并做更多的数学运算

    【讨论】:

    • 感谢您让我知道Stack,这是result 有没有办法获取图像的heightwidth 而不是Expand
    • 哇!!!,真的好用,非常感谢,只有一件事是如何用pointXPercentpointyPercent从JSON调用它,我是代码的新手,可以你帮帮我,还是我应该创建另一个帖子?
    • 如果刚开始,我会推荐 - 请阅读文档并介绍给json parsing,如果出现问题,请提出 =)
    【解决方案2】:

    您可以使用 Align 来选择堆栈中的位置,如下所示:

    Stack(children: [
        child: Align(
            alignment: Alignment(-.40, -.90),
            child: MyPictureWidget()
        ),
    ]);
    

    更好,因为您不需要获得约束。 :) Alignment(0, 0) 将位于中心

    【讨论】:

    • 是的,但是如何对齐image 而不是Expand
    猜你喜欢
    • 2017-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-06
    • 1970-01-01
    • 1970-01-01
    • 2012-11-26
    • 1970-01-01
    相关资源
    最近更新 更多