Flutter 颤振:有没有一种方法可以从类中定义的常量中选择一个随机常量?
我想定义一些“自定义”枚举颜色。由于flatter不支持自定义枚举数,我去了flatter源代码查看它们在Flutter 颤振:有没有一种方法可以从类中定义的常量中选择一个随机常量?,flutter,Flutter,我想定义一些“自定义”枚举颜色。由于flatter不支持自定义枚举数,我去了flatter源代码查看它们在颜色方面做得如何,我用同样的方法制作了我的枚举数: class SkinColors { // This class is not meant to be instantiated or extended; this constructor // prevents instantiation and extension. // ignore: unused_element S
颜色方面做得如何,我用同样的方法制作了我的枚举数:
class SkinColors {
// This class is not meant to be instantiated or extended; this constructor
// prevents instantiation and extension.
// ignore: unused_element
SkinColors._();
static const Color tanned = Color(0xFFFD9841);
static const Color yellow = Color(0xFFF9D562);
static const Color pale = Color(0xFFFFDBB4);
static const Color light = Color(0xFFEDB98A);
static const Color brown = Color(0xFFD08B5B);
static const Color darkBrown = Color(0xFFAE5D29);
static const Color black = Color(0xFF614335);
}
现在,我想从这个列表中随机选择一种颜色。我又去了材质/颜色。dart
,我检查了他们用原色做了什么,我做了类似的事情。我将此代码添加到我的类中:
static const List<Color> colors = <Color>[
tanned,
yellow,
pale,
light,
brown,
darkBrown,
black,
];
static random() => colors[Random().nextInt(colors.length)];
我希望用户不需要知道他/她使用的是枚举还是类,并且可以以相同的方式使用它们
因此,我更喜欢一种可以使用的方法:
var mySkin=SkinType.dry;
var mySkinColor=SkinColor.tanned;
使用枚举的解决方案
。
下面,我定义了一个SkinColor
枚举。然后,由于Dart扩展
,我将每个SkinColor
值的颜色代码定义为一个映射,以及一个颜色getter
我还添加了一个static SkinColor get random
,您可以从扩展访问它。这会给你一个随机的肤色
import 'dart:math' show Random;
import 'dart:ui' show Color;
void main() {
SkinColor randomSkinColor = SkinColor.values[Random().nextInt(SkinColor.values.length)];
print(randomSkinColor.color);
randomSkinColor = SkinColorX.random;
print(randomSkinColor.color);
}
enum SkinColor {
tanned,
yellow,
pale,
light,
brown,
darkBrown,
black,
}
extension SkinColorX on SkinColor {
static const colors = {
SkinColor.tanned : Color(0xFFFD9841),
SkinColor.yellow : Color(0xFFF9D562),
SkinColor.pale : Color(0xFFFFDBB4),
SkinColor.light : Color(0xFFEDB98A),
SkinColor.brown : Color(0xFFD08B5B),
SkinColor.darkBrown : Color(0xFFAE5D29),
SkinColor.black : Color(0xFF614335),
};
Color get color => colors[this];
static SkinColor get random => SkinColor.values[Random().nextInt(SkinColor.values.length)];
}
使用DelegatingMap的解决方案
下面是另一个使用DelegatingMap
的解决方案
SkinColor
定义为:
class SkinColor extends DelegatingMap<String, Color> {
static const Map<String, Color> colors = {
'tanned': Color(0xFFFD9841),
'yellow': Color(0xFFF9D562),
'pale': Color(0xFFFFDBB4),
'light': Color(0xFFEDB98A),
'brown': Color(0xFFD08B5B),
'darkBrown': Color(0xFFAE5D29),
'black': Color(0xFF614335),
};
Map<String, Color> get delegate => colors;
static Color get random {
return colors.values.elementAt(Random().nextInt(colors.values.length));
}
}
class SkinColor扩展了DelegatingMap{
静态常量贴图颜色={
“鞣制”:颜色(0xFFFD9841),
“黄色”:颜色(0xFFF9D562),
“苍白”:颜色(0xFFFFDBB4),
“灯光”:颜色(0xFFEDB98A),
“棕色”:颜色(0xFFD08B5B),
“暗褐色”:颜色(0xFFAE5D29),
“黑色”:颜色(0xFF614335),
};
Map get delegate=>colors;
静态颜色变得随机{
返回colors.values.elementAt(Random().nextInt(colors.values.length));
}
}
而且用法非常基本:
SkinColor.colors;//所有颜色列表作为“地图”`
SkinColor()[“晒黑”];//特定的肤色`
SkinColor.random;//随意的颜色`
完整源代码
import'dart:math'随机显示;
进口“包装:颤振/材料.省道”;
进口“包装:颤振钩/颤振钩.省道”;
导入“包装:quiver/collection.dart”;
void main(){
runApp(
材料聚丙烯(
debugShowCheckedModeBanner:false,
标题:“颤振演示”,
主页:主页(),
),
);
}
类主页扩展了小部件{
@凌驾
小部件构建(构建上下文){
最终选择=使用状态(SkinColor.random);
返回脚手架(
正文:专栏(
crossAxisAlignment:crossAxisAlignment.stretch,
儿童:[
容器(
填充:边缘设置。全部(8),
颜色:_选定。值,
子项:DropdownButtonFormField(
商品:SkinColor.colors
.map((名称、颜色){
返回映射条目(
名称
下拉菜单项(
值:颜色,
子项:文本(名称),
));
})
价值观
.toList(),
值:_selected.value,
onChanged:(newValue)=>\u selected.value=newValue,
),
),
尺寸箱(高度:2.0),
扩大(
子项:GridView.count(
交叉轴计数:5,
儿童方面:1,
主轴间距:2,
横轴间距:2,
子项:List.generate(
50,
()=>ColoredBox(颜色:SkinColor.random),
),
),
),
],
),
);
}
}
类SkinColor扩展了DelegatingMap{
静态常量贴图颜色={
“鞣制”:颜色(0xFFFD9841),
“黄色”:颜色(0xFFF9D562),
“苍白”:颜色(0xFFFFDBB4),
“灯光”:颜色(0xFFEDB98A),
“棕色”:颜色(0xFFD08B5B),
“暗褐色”:颜色(0xFFAE5D29),
“黑色”:颜色(0xFF614335),
};
Map get delegate=>colors;
静态颜色变得随机{
返回colors.values.elementAt(Random().nextInt(colors.values.length));
}
}
谢谢您的回答。我喜欢你的方法,这是一个很好的方法,我不知道扩展。但是,就在这个例子中,你也在两个地方复制肤色(就像我的方法一样),我想找到一种方法,所以当我添加一种新颜色时,我只能在一个地方添加。同时,我更喜欢使用var mySkinColor=SkinColor.light
,根据您的方法,我必须使用mySkinColor=SkinColor.light.color
。(我更新了我的问题)谢谢你,这样一个非常完整的答案!!!但我认为我不能做像var mySkinColor=SkinColor.tanned代码>dart中是否有类似于magic PHP\uu get()
的方法?()因为这样,我可以制作一个神奇的\uu get()
方法,返回SkinColor()['tanned']我有一个好消息和一个坏消息要告诉你。好消息是,它确实存在于dart:mirrors
中。但最坏的消息是,它对Flutter不起作用。不过,您可能会找到一些提前模拟反射的包。查看可反射的
。不过,我个人从未用过。谢谢你给我更多的选择。正如我所看到的,没有一种简单的方法可以实现我所期待的。但我真的很感激你给我的选择。
class SkinColor extends DelegatingMap<String, Color> {
static const Map<String, Color> colors = {
'tanned': Color(0xFFFD9841),
'yellow': Color(0xFFF9D562),
'pale': Color(0xFFFFDBB4),
'light': Color(0xFFEDB98A),
'brown': Color(0xFFD08B5B),
'darkBrown': Color(0xFFAE5D29),
'black': Color(0xFF614335),
};
Map<String, Color> get delegate => colors;
static Color get random {
return colors.values.elementAt(Random().nextInt(colors.values.length));
}
}
import 'dart:math' show Random;
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:quiver/collection.dart';
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
home: HomePage(),
),
);
}
class HomePage extends HookWidget {
@override
Widget build(BuildContext context) {
final _selected = useState(SkinColor.random);
return Scaffold(
body: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
padding: EdgeInsets.all(8),
color: _selected.value,
child: DropdownButtonFormField<Color>(
items: SkinColor.colors
.map((name, color) {
return MapEntry(
name,
DropdownMenuItem<Color>(
value: color,
child: Text(name),
));
})
.values
.toList(),
value: _selected.value,
onChanged: (newValue) => _selected.value = newValue,
),
),
SizedBox(height: 2.0),
Expanded(
child: GridView.count(
crossAxisCount: 5,
childAspectRatio: 1,
mainAxisSpacing: 2,
crossAxisSpacing: 2,
children: List.generate(
50,
(_) => ColoredBox(color: SkinColor.random),
),
),
),
],
),
);
}
}
class SkinColor extends DelegatingMap<String, Color> {
static const Map<String, Color> colors = {
'tanned': Color(0xFFFD9841),
'yellow': Color(0xFFF9D562),
'pale': Color(0xFFFFDBB4),
'light': Color(0xFFEDB98A),
'brown': Color(0xFFD08B5B),
'darkBrown': Color(0xFFAE5D29),
'black': Color(0xFF614335),
};
Map<String, Color> get delegate => colors;
static Color get random {
return colors.values.elementAt(Random().nextInt(colors.values.length));
}
}