flutter - 如何根据不同的 Widget 改变 Widget 的颜色?
问题描述
我正在尝试制作简单的应用程序来显示SvgPicture.assets()
并且用户可以更改SvgPicture()
使用颜色选择器的颜色。
我有 2 个小部件:
- 用于显示
SvgPicture()
称为Svg.dart - main.dart包含
BottomNavigationView
,其中一个选项卡打开颜色选择器,而Svg.dart
我遇到了一些错误,setState(() {})
但我设法以某种方式修复了错误,但它没有改变颜色,当我尝试改变它的背景颜色main.dart
时效果很好。
这是我的代码:
onItemTap()
的方法BottomNavigationBar
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,
),
);
}
}
MultiChildLyoutDelegate
为CustomMultichildLayout
in扩展的类Svg.dart
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;
}
}
解决方案
在 Flutter 中,一切都是小部件,您可以创建自己的自定义小部件。同样,还有层次结构和状态等概念。
无状态小部件是StatelessWidget
诸如标签、背景、标题或其他任何东西。
有状态的小部件是一种StatefulWidget
变化的东西,例如开关、动画背景、页面等。还有一个InheritedWidget
但那是另一个主题。
setState
用于更新该StatefulWidget
小部件的状态,要从父级更新子级,可以使用子级的属性。当被调用时,它会在必要时重建小部件及其子项。setState
小Container
部件有一个color
属性。
Container(
color: colorParent,
)
您的自定义小部件还可以具有任何属性,例如color
orsize
或colorChild
。
ChildWidget(
colorChild: colorParent,
)
当您想访问您使用colorChild
的 a 的属性时,当它没有状态时,您可以简单地使用.StatefulWidget
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'),
);
}
}
推荐阅读
- python - 获取名为 region_name 的第三个输入,它是一个字符串。将 region_list 中包含的适当字符串附加到您的打印语句中
- python - 通过 Python 连接到 UCCX 数据库 (Informix)
- javascript - HTML & CSS - DOM 遍历
- python-3.x - TypeError: Sporsmaal() 没有参数
- ruby-on-rails - 如何在 UTC 中为过去日期写一个 ruby on rails 条件?
- sql - PostgreSQL json_build_object 嵌套
- yaml - 订购者连接被拒绝 Hyperledger Fabric
- r - 通过在数据表中动态创建列名进行计算
- haskell - Haskell 用于推测执行条件/替代的策略
- postgresql - PostgreSQL:如何找出没有主副本的副本类型?