gpt4 book ai didi

flutter - 在不同屏幕尺寸的特定像素位置绘制小部件

转载 作者:行者123 更新时间:2023-12-04 02:32:53 31 4
gpt4 key购买 nike

我正在尝试构建一个简单的 Flutter 应用程序,该应用程序显示全屏背景图像,并使用户能够将某些小部件(即基本圆圈)从预定义的开始位置(以像素为单位)拖动到预定义的目标位置(也以像素为单位)。以下来自 TouchSurgery 应用程序的屏幕截图显示了与我想要实现的非常相似的设置(绿色圆圈 = 起始位置,白色圆圈 = 目标位置):
enter image description here
在这一点上我最关心的是不同 屏幕尺寸 .假设我们有一台分辨率为 750 x 1334 的 iPhone SE(第二代) .我可以创建以下具有所需分辨率的背景图像,并随机确定所需的起始位置位于坐标 (430, 949) (为简单起见,我们可以忽略目标位置):
enter image description here
使用以下小部件,我可以渲染一个圆形 Container在起点之上:

class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
var dpr = MediaQuery.of(context).devicePixelRatio;
return Scaffold(
body: Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/iPhoneSE.png"),
fit: BoxFit.fill,
),
),
),
Positioned(
left: 430 / dpr,
top: 949 / dpr,
child: Container(
width: 77.0 / dpr,
height: 77.0 / dpr,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.red,
),
),
),
],
),
);
}
}
生成的图像如下所示:
enter image description here
当我添加 AppBar 时,事情开始变得棘手。或 BottomNavigationBar到我的应用程序。两个小部件的默认高度都是 56 像素。给定一个 devicePixelRatio2在 iPhone SE 上,我需要将背景图片的大小裁剪为 750 x 1110使叠加仍然准确( 1334 - 2 * 56 (AppBar) - 2 * 56 (BottomNavigationBar) )。
对于 iPhone XR 等其他设备,事情变得更加复杂,其中还必须考虑安全区域的大小。对于 Android,还有更多不同的屏幕分辨率可用。
我现在的问题如下:不是为 20-30+ 不同屏幕尺寸创建不同大小的背景图像 - 在 Flutter 中是否有更有效的方法来绘制小部件,例如圆形 Container在与实际屏幕尺寸无关的非常特定的屏幕位置?

最佳答案

您需要在定位您的定位小部件之前获取图像容器的大小。
因为正如你所说,屏幕尺寸可能会改变,与图像尺寸无关(例如屏幕更高但有更大的 SafeArea,或者有一个 appBar 和 BottomAppBar。即使屏幕尺寸增加,图像也可能是相同的尺寸.. .)
由于您的定位小部件和图像容器使用相同的构建方法,因此您必须使用 LayoutBuilder小部件在继续构建定位小部件之前跟踪图像容器的大小。
就是这样:
(我已经包含了 2 个完全有效的示例,以便您可以看到红色圆圈与背景图像保持相同的相对位置,即使图像大小发生变化。您更正的代码是第一个示例)。
示例 1


/*
I used these calculated ratios based on your code.
Feel free to use any other way to get these ratios.
The method will be the same.

- The image takes all the available width and height

- The positioned element is postioned :
58.9% from the left of the image container
72% from the top of the image container

- The inner container's:
width is 7.129629629% of the Image Container's width,
height is 4.292084726% of the Image Container's height,
*/

import 'package:flutter/material.dart';

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}

class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, constraints) { //This is key
return Scaffold(
body: Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/iPhoneSE.png"),
fit: BoxFit.fill,
),
),
),
Positioned(
left: 0.589 * constraints.maxWidth,
top: 0.72 * constraints.maxHeight,
child: Container(
width: 0.07129629629 * constraints.maxWidth,
height: 04292084726 * constraints.maxHeight,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.red,
),
),
),
],
),
);
});
}
}

示例 1 图像:
enter image description here
示例 2(带有 AppBar 和 BottomAppBar)
import 'package:flutter/material.dart';

void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}

class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Title of app"),
),
body: LayoutBuilder(builder: (context, constraints) {
return Column(
children: <Widget>[
Flexible(
fit: FlexFit.loose,
child: Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/iPhoneSE.png"),
fit: BoxFit.fill,
),
),
),
Positioned(
left: 0.589 * constraints.maxWidth,
top: 0.72 * constraints.maxHeight,
child: Container(
width: 0.07129629629 * constraints.maxWidth,
height: 0.04292084726 * constraints.maxHeight,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.red,
),
),
),
],
),
),
],
);
}),
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.home,
),
title: Text("Home")),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle), title: Text("Profile")),
],
),
);
}
}

示例 2 图像:
enter image description here

关于flutter - 在不同屏幕尺寸的特定像素位置绘制小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63176229/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com