英文:
Show half a widget (an icon)
问题
我想实现与下面这个类似的效果:
这个想法是在灰色的图标上完全显示一个图标,然后在其上方显示相同的图标,但颜色不同,并且只在屏幕上显示部件的一部分。我尝试使用Stack
和Align
(heightFactor
)来实现,但效果不好。
有什么想法吗?
编辑: 这是我尝试的代码:
class TestWidget extends StatefulWidget {
const TestWidget({Key? key});
@override
_TestWidgetState createState() => _TestWidgetState();
}
class _TestWidgetState extends State<TestWidget> {
GlobalKey aKey = GlobalKey();
@override
Widget build(BuildContext context) {
return Container(
color: Colors.grey[200],
child: Align(
alignment: const Alignment(-0.85, -0.85),
child: Wrap(children: [
Stack(
children: [
Center(
child: Icon(
key: aKey,
icon: Icons.thunderstorm,
color: Colors.blueGrey,
size: 100)),
Column(
children: [
LayoutBuilder(builder: (context, _) {
RenderBox renderbox =
aKey.currentContext!.findRenderObject() as RenderBox;
return SizedBox(height: renderbox.size.height * 0.25);
}),
const ClipRect(
child: Align(
heightFactor:
0.5, // Set this to 0.8 to see the displaced, unmatching image.
child: Icon(Icons.thunderstorm,
color: Colors.red, size: 100),
))
],
)
],
)
]),
));
}
}
分别是heightFactor
为0.5和0.8时的输出:
英文:
I would like to achive an effect similar to the next one:
The idea is to have a fully displayed Icon in grey, and then in top of it the same Icon but in another color and only showing on the screen a percentage of the widget on top. I've tried to do it with Stack
and Align
(heightFactor
) but nothing worked well.
Any ideas?
EDIT: Here it's the code I tried:
class TestWidget extends StatefulWidget {
const TestWidget({super.key});
@override
State<TestWidget> createState() => _TestWidgetState();
}
class _TestWidgetState extends State<TestWidget> {
GlobalKey aKey = GlobalKey();
@override
Widget build(BuildContext context) {
return Container(
color: Colors.grey[200],
child: Align(
alignment: const Alignment(-0.85, -0.85),
child: Wrap(children: [
Stack(
children: [
Center(
child: Icon(
key: aKey,
Symbols.thunderstorm,
color: Colors.blueGrey,
size: 100)),
Column(
children: [
LayoutBuilder(builder: (context, _) {
RenderBox renderbox =
aKey.currentContext!.findRenderObject() as RenderBox;
return SizedBox(height: renderbox.size.height * 0.25);
}),
const ClipRect(
child: Align(
heightFactor:
0.5, // Set this to 0.8 to see the displaced, unmatching image.
child: Icon(Symbols.thunderstorm,
color: Colors.red, size: 100),
))
],
)
],
)
]),
));
}
}
These are the outputs for 0.5 and 0.8 heightFactor
, respectively:
答案1
得分: 0
受到@pskink答案的启发,我想出了这个可行的示例:
class TestWidget extends StatefulWidget {
const TestWidget({Key? key});
@override
State<TestWidget> createState() => _TestWidgetState();
}
class _TestWidgetState extends State<TestWidget> {
GlobalKey aKey = GlobalKey();
double percent = 0.3;
@override
Widget build(BuildContext context) {
return Container(
color: Colors.grey[200],
child: Align(
alignment: const Alignment(-0.85, -0.85),
child: Wrap(
children: [
Stack(
children: [
Center(
child: Icon(
key: aKey,
Icons.thunderstorm,
color: Colors.blueGrey,
size: 100,
),
),
Column(
children: [
LayoutBuilder(builder: (context, _) {
RenderBox renderbox =
aKey.currentContext!.findRenderObject() as RenderBox;
return SizedBox(
height: renderbox.size.height * (1 - percent),
);
}),
ClipRect(
child: Align(
heightFactor: percent,
alignment: Alignment.bottomCenter,
child: const Icon(
Icons.thunderstorm,
color: Colors.red,
size: 100,
),
),
),
],
),
],
),
],
),
),
);
}
}
这个示例可以按预期工作。之所以能够实现这个效果,是因为如果你将有颜色的小部件对齐到顶部,heightFactor
会从顶部开始裁剪。你只需要将新的裁剪小部件插入到一个带有 SizedBox 的 Column 中,SizedBox 的高度为你从有颜色的小部件中减少的高度。
我无法弄清楚如何配置 @pskink 建议的 Rect
对象,如果他能提供一个详细的代码,完善这个解决方案,将不胜感激。
英文:
Inspired by @pskink's answer, I came up with this working example:
class TestWidget extends StatefulWidget {
const TestWidget({super.key});
@override
State<TestWidget> createState() => _TestWidgetState();
}
class _TestWidgetState extends State<TestWidget> {
GlobalKey aKey = GlobalKey();
double percent = 0.3;
@override
Widget build(BuildContext context) {
return Container(
color: Colors.grey[200],
child: Align(
alignment: const Alignment(-0.85, -0.85),
child: Wrap(children: [
Stack(
children: [
Center(
child: Icon(
key: aKey,
Symbols.thunderstorm,
color: Colors.blueGrey,
size: 100)),
Column(
children: [
LayoutBuilder(builder: (context, _) {
RenderBox renderbox =
aKey.currentContext!.findRenderObject() as RenderBox;
return SizedBox(
height: renderbox.size.height * (1 - percent));
}),
ClipRect(
child: Align(
heightFactor: percent,
alignment: Alignment.bottomCenter,
child: const Icon(Symbols.thunderstorm,
color: Colors.red, size: 100)),
)
],
)
],
)
]),
));
}
}
Which works as desired. The reason for it is because if you align the coloured widget to the top, the heightFactor
cuts starting from there. You only need to insert the new cut widget in a Column with a SizedBox with the height you loose from the coloured one.
I couldn't figure out how to configure the Rect
object @pskink suggested, and it would be appreciated if he could give a detailed code with his full solution to complement this one.
答案2
得分: 0
你可以使用ShaderMask
小部件来使用gradient
颜色对图标进行遮罩,并使用stop
属性进行突变的颜色变化。
我创建了这个演示,你可以看到一个例子。运行它并点击图标以查看变化。
英文:
You can use ShaderMask
widget to mask the icon with a gradient
color, and use the stop
property for the sudden color change.
I created this demo so you can see an example. Run it and click on the icon to see the changes.
答案3
得分: -1
一种实现方法是使用一个Stack和两个图标,将一个图标放在另一个图标上方,并使用ClipRect将上方图标切割成一半,显示底部一半的图标。以下是一个示例:
Container(
width: 100,
child: Stack(
children: [
Icon(
Icons.bolt,
size: 100,
color: Colors.grey,
),
ClipRect(
child: Align(
alignment: Alignment.topCenter,
heightFactor: 0.5,
child: Icon(
Icons.bolt,
size: 100,
color: Colors.yellow,
),
),
),
],
),
)
英文:
One way to achieve that is using an Stack and two icons, placing one icon above another, and using a ClipRect to cut superior's icons in half, showing the bottom half of the icon behind. Here's an example:
Container(
width: 100,
child: Stack(
children: [
Icon(
Icons.bolt,
size: 100,
color: Colors.grey,
),
ClipRect(
child: Align(
alignment: Alignment.topCenter,
heightFactor: 0.5,
child: Icon(
Icons.bolt,
size: 100,
color: Colors.yellow,
),
),
),
],
))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论