关键词:
【中文标题】如何根据不同的 Widget 改变 Widget 的颜色?【英文标题】:How to change the color of a Widget based on a different Widget? 【发布时间】:2021-06-29 18:21:24 【问题描述】:我正在尝试制作显示SvgPicture.assets()
的简单应用程序,用户可以使用颜色选择器更改SvgPicture()
的颜色。
我有 2 个小部件:
-
用于显示
SvgPicture()
将其称为 Svg.dart
main.dart 包含 BottomNavigationView
,其中一个选项卡打开颜色选择器,Svg.dart
我在使用setState(() )
时遇到了一些错误,但我设法以某种方式修复了错误,但它并没有改变颜色,当我尝试更改main.dart
的背景颜色时,它工作得很好。
这是我的代码:
BottomNavigationBar
的onItemTap()
方法
void _onItemTap(int index)
setState(()
if (index == 0)
// First Tab
if (index == 1)
// SecondTab
if (index == 2)
// Third Tab
if (index == 3)
showDialog(
context: context,
builder: (BuildContext context)
return AlertDialog(
content:
SingleChildScrollView(
child: new ColorPicker(
pickerColor: Colors.red,
onColorChanged: (Color colorChanged)
color = colorChanged;
// (color) is assigned default value of Colors.red
// here I'm trying to assign new value to (color)
,
),//ColorPicker
),//SingleChildScrollView
);//AlertDialog
);
);
然后在Svg.dart
中我创建了另一个变量Color picked = Colors.red
并将红色指定为默认值。这就是Svg.dart
小部件代码的样子:
Widget build(BuildContext context)
setState(()
picked = main().createState().color;
);
return CustomMultiChildLayout(
delegate: TempDelegate(
position: Offset.zero
),
children: [
buildLayoutId(ids.shirtId, MyConstants.shirt, picked)
],
);
LayoutId buildLayoutId(Object id, String item, Color color)
return LayoutId(
id: id,
child: SvgPicture.asset(
item,
color: color,
),
);
我尝试寻找颤振文档,但我真的不知道问题是如何/在哪里,也没有找到教程,请帮助
编辑
这是main.dart
class Main extends StatefulWidget
@override
_MainState createState() => _MainState();
class _Main extends State<Main>
int _slectedIndex = 0;
Color color = MyConstants.darkWhite;
@override
Widget build(BuildContext context)
return Scaffold(
backgroundColor: Colors.black,
body: Center(
child: Svg(),
),
bottomNavigationBar: BottomNavigationBar(
items: const<BottomNavigationBarItem>[
BottomNavigationBarItem(
label: "",
icon: Icon(Icons.home),
),
BottomNavigationBarItem(
label: "",
icon: Icon(Icons.home),
),
BottomNavigationBarItem(
label: "",
icon: Icon(Icons.home),
),
BottomNavigationBarItem(
label: "",
icon: Icon(Icons.home),
),
],
onTap: _onItemTap,
),
);
void _onItemTap(int index)
setState(()
if (index == 0)
// do something
if (index == 1)
// do something
if (index == 2)
// do something
if (index == 3)
showDialog(
context: context,
builder: (BuildContext context)
return AlertDialog(
content:
SingleChildScrollView(
child: new ColorPicker(
pickerColor: Colors.red,
onColorChanged: (Color colorChanged)
setState(()
color = colorChanged;
);
,
),
),
);
);
);
和Svg.dart
class Svg extends StatefulWidget
//Color picked;
@override
SvgState createState() => Svg();
class SvgState extends State<Svg>
@override
Widget build(BuildContext context)
return CustomMultiChildLayout(
delegate: SvgDelegate(
position: Offset.zero
),
children: [
buildLayoutId(ids.shirtId, MyConstants.shirt, CreateKit().createState().color)
],
);
LayoutId buildLayoutId(Object id, String item, Color color)
return LayoutId(
id: id,
child: SvgPicture.asset(
item,
color: color,
),
);
在Svg.dart
中为CustomMultichildLayout
扩展MultiChildLyoutDelegate
的类
class SvgDelegate extends MultiChildLayoutDelegate
final Offset position;
SvgDelegate(
this.position
);
@override
void performLayout(Size size)
Size leadSize = Size.zero;
itemLayout(leadSize, size, ids.shirtId);
void itemLayout(Size leadSize, Size size, Object id)
if(hasChild(id))
leadSize = layoutChild(
id,
BoxConstraints.loose(size),
);
@override
bool shouldRelayout(TempDelegate oldDelegate)
return oldDelegate.position != position;
【问题讨论】:
如果svg
和BottomNavigationBar
在main
中,color = colorChanged;
应该被 setState 包围。我认为您不需要在svg
中使用picked
,全局变量color
就可以了。你能分享main
的代码吗?
你能分享你完整的 StatefulWidget 代码吗?顺便说一句,在构建期间不要使用setState(())
@EdwardLi 我应用了更改并分享了编辑后的代码,请查看。
@Gilang 我不确定是否理解你,我是 noop 哈哈
【参考方案1】:
在 Flutter 中,一切都是小部件,您可以创建自己的自定义小部件。 同样,还有层次结构和状态等概念。
无状态小部件是 StatelessWidget
,例如标签、背景、标题或其他任何东西。
有状态的小部件是 StatefulWidget
,它是可以变化的东西,例如开关、动画背景、页面等。还有一个 InheritedWidget
,但这是另一个主题。
setState
在StatefulWidget
中用于更新that 小部件的状态,要从父级更新子级,可以使用子级的属性。
当setState
被调用时,它会在必要时重建小部件及其子部件。
Container
小部件具有 color
属性。
Container(
color: colorParent,
)
您的自定义小部件还可以具有任何属性,例如 color
或 size
或 colorChild
。
ChildWidget(
colorChild: colorParent,
)
当你想访问StatefulWidget
的colorChild
属性时,你使用widget.colorChild
,当它没有状态时,你可以简单地使用colorChild
。
import 'package:flutter/material.dart';
void main()
runApp(MyApp());
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return MaterialApp(
theme: ThemeData.dark(),
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(),
body: Center(
child: Parent(),
),
),
);
class Parent extends StatefulWidget
@override
ParentState createState() => ParentState();
class ParentState extends State<Parent>
// Define the color in parent
Color colorParent = Colors.red;
@override
Widget build(BuildContext context)
return Scaffold(
backgroundColor: Colors.white,
body: Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
// Pass the color as a property
ChildWidget(colorChild: colorParent),
VerticalDivider(color: colorParent),
Child2Widget(colorChild: colorParent),
],
),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
label: "Tap to Blue",
icon: Icon(Icons.home),
),
BottomNavigationBarItem(
label: "Tap to Orange",
icon: Icon(Icons.dashboard),
),
BottomNavigationBarItem(
label: "Tap to Green",
icon: Icon(Icons.palette),
),
// ...
],
onTap: _onItemTap,
),
);
void _onItemTap(index)
// ...
switch (index)
case 0:
setState(()
// Update color in parent
colorParent = Colors.blue;
);
break;
case 1:
setState(()
colorParent = Colors.orange;
);
break;
case 2:
setState(()
colorParent = Colors.green;
);
break;
class ChildWidget extends StatefulWidget
// Define color in child
final Color colorChild;
const ChildWidget(Key key, this.colorChild) : super(key: key);
@override
ChildWidgetState createState() => ChildWidgetState();
class ChildWidgetState extends State<ChildWidget>
@override
Widget build(BuildContext context)
return Container(
height: 100,
width: 100,
// Use it
color: widget.colorChild,
child: Text('Child 1'),
);
class Child2Widget extends StatelessWidget
// Define color in child
final Color colorChild;
const Child2Widget(Key key, this.colorChild) : super(key: key);
@override
Widget build(BuildContext context)
return Container(
height: 100,
width: 100,
// Use it
color: colorChild,
child: Text('Child 2'),
);
【讨论】:
成功了!非常感谢你,现在我对颤振的工作原理有了更好的理解。我还有一个问题要了解无状态/完整,当 colorParent 更改时,无状态和有状态小部件颜色都会发生变化,是不是因为Parent
在每次点击时都会以不同的颜色重建,因此子小部件会跟随父小部件并重建?因为我对它构建一次的无状态小部件的理解就是这样。再次感谢您的解释,这非常有帮助
不客气!,是的,你是对的,statelessWidget
不会重建自己,也就是说,无状态的任何内部操作都不会重建它(这就是为什么 MyApp
是无状态的),但在这种情况下,有一个外部 parent
代理会杀死它(哎哟!)并创建一个新代理。但是,如果要创建不重新构建的小部件,可以在任何小部件之前添加const
(这对性能非常有用),但您不能再在其参数中传递变量,只能传递常量。【参考方案2】:
请更改默认选择器颜色值,请分配包含任何颜色值的变量,onTabItem 更改该变量的值。
颜色_color = Colors.red;
ColorPicker(pickerColor: _color, onColorChanged: (Color colorChanged) setState(() => _color = colorChanged;,),
【讨论】:
Flutter中如何改变Widget在Column或Row中的显示顺序
】Flutter中如何改变Widget在Column或Row中的显示顺序【英文标题】:howtochangethedisplayingorderoftheWidgetsinColumnorRowinFlutter【发布时间】:2021-09-0602:13:50【问题描述】:我正在创建一个基本的聊天应用程序,其中我正在使用一个行小部件... 查看详情
如何在 Widget 之外调度 Bloc 事件?
】如何在Widget之外调度Bloc事件?【英文标题】:HowtodispatchBloceventsoutsideofWidget?【发布时间】:2020-12-0709:10:15【问题描述】:我是Bloc架构的新手,最近看了一些教程。我有一个StatelessWidget页面,在里面我使用BlocProvider在我的UI中... 查看详情
odoo内部视图格式——widget
Odoo视图层的filed有很多种显示风格,根据字段具体内容的不同,可以通过widget属性指明对应的显示风格。其中,内置的有以下几种:widget="statusbar"头部状态条标签widget="email"电子邮件地址标签widget="selection"下拉选择标签widget="mail_... 查看详情
odoo内部视图格式——widget
Odoo视图层的filed有很多种显示风格,根据字段具体内容的不同,可以通过widget属性指明对应的显示风格。其中,内置的有以下几种:widget="statusbar"头部状态条标签widget="email"电子邮件地址标签widget="selection"下拉选择标签widget="mail_... 查看详情
ios14widget小组件开发(widgetextension)
...要渲染的属性。Timeline的刷新策略是会延迟的,并不一定根据你设定的时间精确刷新。同时官方说明了每个widget窗口小部件每天接收的刷新都会有数量限制TimelineProvider官方解释渲染Widget所需的数据模型,需要遵守TimelineEntry协议... 查看详情
如何根据 Widget Kivy 属性更新**动态添加的**椭圆(不使用 Builder)的颜色?
】如何根据WidgetKivy属性更新**动态添加的**椭圆(不使用Builder)的颜色?【英文标题】:HowdoIupdatetheColorofa**dynamicallyadded**Ellipse(notusingBuilder)accordingtoWidgetKivyproperties?【发布时间】:2013-06-0803:05:08【问题描述】:这与thisotherquestion... 查看详情
如何根据 Widget Kivy 属性更新**动态添加的**椭圆(不使用 Builder)的颜色?
】如何根据WidgetKivy属性更新**动态添加的**椭圆(不使用Builder)的颜色?【英文标题】:HowdoIupdatetheColorofa**dynamicallyadded**Ellipse(notusingBuilder)accordingtoWidgetKivyproperties?【发布时间】:2013-06-0803:05:08【问题描述】:这与thisotherquestion... 查看详情
如何将 Future<Widget> 作为小部件返回
】如何将Future<Widget>作为小部件返回【英文标题】:HowtoreturnFuture<Widget>asWidget【发布时间】:2020-10-2118:12:15【问题描述】:下面的代码可能看起来有点复杂,但基本上下面的函数使用一个switchcase根据导航栏的索引号返回... 查看详情
将 Widget Builders 之类的类成员提取到不同的文件中?
...:在为我的Flutter应用程序开发一些屏幕时,我经常需要根据屏幕状态动态渲染小部件。对于需要创建单独的小部件并包含它的情况,我会这样做。但是,在许多用例中,我需要渲染的内容不适合小部件 查看详情
android开发桌面时钟,怎么根据系统时间的变化更新widget
雏形已经写好了,但是就是不知道怎么根据系统时间的变化来更新Widget的时间,百度找了半天也没有找到有用的资料,有个网站有源代码的下载,但是要付费的会员才能下(汗)第一次学着写Widget,很多地方都不懂,哪位大侠有... 查看详情
Flutter 自定义布局,根据子元素决定 widget 的大小
】Flutter自定义布局,根据子元素决定widget的大小【英文标题】:Fluttercustomlayout,decidewidget\'ssizebasedonitschild【发布时间】:2020-10-3014:11:59【问题描述】:understandingconstraints文章对于了解布局的工作原理非常有用。但是,我在创建... 查看详情
如何改变androidprogressbar默认颜色
如何改变AndroidProgressbar默认颜色默认情况下IndeterminateProgressbar是白色的,如果容器的背景也是白色的,这样就根本看不到Progressbar了。幸好Android自带了一些反转样式,你可以采用其中一个合适的:http://stackoverflow.com/questions/2638161... 查看详情
Android-Widget:使用 RemoteView 更改 ListView 选择器颜色
...view设置appWidget上存在的listView的选择器颜色。基本上我想根据用户选择的主题来改变它的颜色,所以我不能在布局xml 查看详情
flutter基础组件:widget简介(代码片段)
...中几乎所有的对象都是一个Widget。与原生开发中“控件”不同的是,Flutter中的Widget的概念更广泛,它不仅可以表示UI元素,也可以表示一些功能性的组件如:用于手势检测的GestureDetectorwidget、用于APP主题数据传递的Theme等等,而... 查看详情
tkinter中widget配置
通过设置属性来改变Widget的外观常见的属性包括text(显示的文字)、color(前景色和背景色)、size(宽度和高度)、commandcallbacks(点击后的回调函数)等等1.设置属性,有3种方式:1)在创建Widget时,通过关键字参数设定widgetclass(master,opti... 查看详情
Flutter Bloc 如何从 Widget 本身更新 BlocBuilder 中的 Widget?
】FlutterBloc如何从Widget本身更新BlocBuilder中的Widget?【英文标题】:FlutterBlocHowtoupdateWidgetinBlocBuilderfromtheWidgetitself?【发布时间】:2021-04-2301:10:51【问题描述】:如何使用Slider从blocWidget本身更新Bloc小部件?图表数据的事件是从另... 查看详情
android如何自定义menu
最近想做个一排6个操作的menu但是默认的menu会换行查了下资料和论坛,很多人说使用PopupWindow,但是这个感觉和menu有很大的区别,因为显示Popupwindow后,界面其他部分不能点击了,他也不会被点击隐藏还有人使用布局的显示隐藏实... 查看详情
如何将 Qline 坐标发送到 QPainter Widget
】如何将Qline坐标发送到QPainterWidget【英文标题】:howtosendQlinecoordinatetoaQPainterWidget【发布时间】:2011-05-2805:22:19【问题描述】:我创建了一个QwidgetForm_temp,它根据在父窗口小部件MainWindow中创建的数据数组绘制线条。我面临的问... 查看详情