Dartで16進法と10進法を変換する時のコピペ。
経緯
Flutterをはじめて2週間の頃、
はじめてのアプリとして【色をシャッフルするアプリ】を作ろうとしました。
その際、色を16進法と10進法の変換する機能をスマートに作りたかったのですが、
全部書く方が早そうだったので、考える前に以下のコードを書いてました。
(間違えがあれば、コメント頂けると幸いです。)
似た境遇の方、お使い下さい。
環境
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.8.1, on macOS 12.1 21C52 darwin-arm, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 13.2.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2020.3)
[✓] VS Code (version 1.63.0)
[✓] Connected device (2 available)
• No issues found!
説明
・ decimalList:00から255までを順番に並べた10進法のdynamic型のList
・ hexList:'00'から'FF'まで順番に並べた16進法のdynamic型のList
・ decimalList[decimalListのindex]みたいな感じで使えます。
コード
model.dart
行数が多くてスクロールが面倒だと思うので、こちらGitHubです。
import 'dart:math';
class Dice {
List<dynamic> decimalList = [
00,
01,
02,
03,
04,
05,
06,
07,
08,
09,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
76,
77,
78,
79,
80,
81,
82,
83,
84,
85,
86,
87,
88,
89,
90,
91,
92,
93,
94,
95,
96,
97,
98,
99,
100,
101,
102,
103,
104,
105,
106,
107,
108,
109,
110,
111,
112,
113,
114,
115,
116,
117,
118,
119,
120,
121,
122,
123,
124,
125,
126,
127,
128,
129,
130,
131,
132,
133,
134,
135,
136,
137,
138,
139,
140,
141,
142,
143,
144,
145,
146,
147,
148,
149,
150,
151,
152,
153,
154,
155,
156,
157,
158,
159,
160,
161,
162,
163,
164,
165,
166,
167,
168,
169,
170,
171,
172,
173,
174,
175,
176,
177,
178,
179,
180,
181,
182,
183,
184,
185,
186,
187,
188,
189,
190,
191,
192,
193,
194,
195,
196,
197,
198,
199,
200,
201,
202,
203,
204,
205,
206,
207,
208,
209,
210,
211,
212,
213,
214,
215,
216,
217,
218,
219,
220,
221,
222,
223,
224,
225,
226,
227,
228,
229,
230,
231,
232,
233,
234,
235,
236,
237,
238,
239,
240,
241,
242,
243,
244,
246,
246,
247,
248,
249,
250,
251,
252,
253,
254,
255,
];
List<dynamic> hexList = [
'00',
'01',
'02',
'03',
'04',
'05',
'06',
'07',
'08',
'09',
'0A',
'0B',
'0C',
'0D',
'0E',
'0F',
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
'1A',
'1B',
'1C',
'1D',
'1E',
'1F',
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
'2A',
'2B',
'2C',
'2D',
'2E',
'2F',
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
'3A',
'3B',
'3C',
'3D',
'3E',
'3F',
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
'4A',
'4B',
'4C',
'4D',
'4E',
'4F',
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
'5A',
'5B',
'5C',
'5D',
'5E',
'5F',
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
'6A',
'6B',
'6C',
'6D',
'6E',
'6F',
70,
71,
72,
73,
74,
75,
76,
77,
78,
79,
'7A',
'7B',
'7C',
'7D',
'7E',
'7F',
80,
81,
82,
83,
84,
85,
86,
87,
88,
89,
'8A',
'8B',
'8C',
'8D',
'8E',
'8F',
90,
91,
92,
93,
94,
95,
96,
97,
98,
99,
'9A',
'9B',
'9C',
'9D',
'9E',
'9F',
'A0',
'A1',
'A2',
'A3',
'A4',
'A5',
'A6',
'A7',
'A8',
'A9',
'AA',
'AB',
'AC',
'AD',
'AE',
'AF',
'B0',
'B1',
'B2',
'B3',
'B4',
'B5',
'B6',
'B7',
'B8',
'B9',
'BA',
'BB',
'BC',
'BD',
'BE',
'BF',
'C0',
'C1',
'C2',
'C3',
'C4',
'C5',
'C6',
'C7',
'C8',
'C9',
'CA',
'CB',
'CC',
'CD',
'CE',
'CF',
'D0',
'D1',
'D2',
'D3',
'D4',
'D5',
'D6',
'D7',
'D8',
'D9',
'DA',
'DB',
'DC',
'DD',
'DE',
'DF',
'E0',
'E1',
'E2',
'E3',
'E4',
'E5',
'E6',
'E7',
'E8',
'E9',
'EA',
'EB',
'EC',
'ED',
'EE',
'EF',
'F0',
'F1',
'F2',
'F3',
'F4',
'F5',
'F6',
'F7',
'F8',
'F9',
'FA',
'FB',
'FC',
'FD',
'FE',
'FF',
];
int randomHexRed = Random().nextInt(256);
int randomHexGreen = Random().nextInt(256);
int randomHexBlue = Random().nextInt(256);
}
main.dart
model.dartと合わせると、ランダム色を出してコピーできるアプリになります。
import 'package:flutter/material.dart';
import 'dart:ui';
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:new_gradient_app_bar/new_gradient_app_bar.dart';
import 'dart:math';
import 'model.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return const MaterialApp(
home: ColoDice(),
debugShowCheckedModeBanner: false,
);
}
}
class ColoDice extends StatefulWidget {
const ColoDice({Key? key}) : super(key: key);
_ColoDiceState createState() => _ColoDiceState();
}
class _ColoDiceState extends State<ColoDice> {
final Dice dice = Dice();
final diceLength = window.physicalSize.height * 0.12;
void showCompletedCopy(BuildContext context) {
showDialog(
context: context,
builder: (context) {
return CupertinoAlertDialog(
title: const Text("Copy completed!"),
content: Text(
"#${dice.hexList[dice.randomHexRed]}${dice.hexList[dice.randomHexGreen]}${dice.hexList[dice.randomHexBlue]}"),
actions: <Widget>[
CupertinoDialogAction(
child: const Text("OK"),
onPressed: () => Navigator.pop(context),
),
],
);
},
);
}
void shuffleColor() {
setState(() {
dice.randomHexRed = Random().nextInt(256);
dice.randomHexGreen = Random().nextInt(256);
dice.randomHexBlue = Random().nextInt(256);
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: NewGradientAppBar(
centerTitle: true,
gradient: const LinearGradient(
colors: [Colors.greenAccent, Colors.green],
),
title: const Text('ColoDice', style: TextStyle(fontSize: 33)),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: diceLength,
height: diceLength,
child: MaterialButton(
child: Icon(
Icons.shuffle_outlined,
size: window.physicalSize.height * 0.04,
color: Colors.white70,
),
elevation: 20.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(80)),
onPressed: () {
shuffleColor();
},
color: Color.fromARGB(
255,
dice.decimalList[dice.randomHexRed],
dice.decimalList[dice.randomHexGreen],
dice.decimalList[dice.randomHexBlue],
),
),
),
const SizedBox(height: 50.0),
Text(
'#${dice.hexList[dice.randomHexRed]}${dice.hexList[dice.randomHexGreen]}${dice.hexList[dice.randomHexBlue]}',
style: TextStyle(
fontSize: 21.0,
fontWeight: FontWeight.w700,
color: Color.fromARGB(
255,
dice.decimalList[dice.randomHexRed],
dice.decimalList[dice.randomHexGreen],
dice.decimalList[dice.randomHexBlue],
),
),
),
const SizedBox(height: 30.0),
Row(
children: [
Text(
'Red: ${dice.decimalList[dice.randomHexRed]}',
style: const TextStyle(
fontSize: 21.0,
fontWeight: FontWeight.w700,
color: Colors.red,
),
),
const SizedBox(width: 12.0),
Text(
'Green: ${dice.decimalList[dice.randomHexGreen]}',
style: const TextStyle(
fontSize: 21.0,
fontWeight: FontWeight.w700,
color: Colors.green,
),
),
const SizedBox(width: 12.0),
Text(
'Blue: ${dice.decimalList[dice.randomHexBlue]}',
style: const TextStyle(
fontSize: 21.0,
fontWeight: FontWeight.w700,
color: Colors.blue,
),
),
],
mainAxisAlignment: MainAxisAlignment.center,
),
],
),
),
floatingActionButton: MaterialButton(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
height: 44,
color: Colors.grey,
textColor: Colors.white,
splashColor: Colors.grey,
hoverColor: Colors.black,
onPressed: () {
setState(() {
var data = ClipboardData(
text: '${dice.hexList[dice.randomHexRed]}'
'${dice.hexList[dice.randomHexGreen]}'
'${dice.hexList[dice.randomHexBlue]}',
);
Clipboard.setData(data);
//コピー完了のお知らせ。
showCompletedCopy(context);
});
},
child: const Text(
'COPY',
style: TextStyle(fontSize: 25.0, fontWeight: FontWeight.w700),
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);
}
}
Discussion
10進→16進は
int.toRadixString(int radix)
というメソッドで変換できます。また16進→10進はint.parse(String source,{int radix})
が使えます。これが最もスマートだと思います。ありがとうざいます。
その変換があるんですね。