🎨

Dartで16進法と10進法を変換する時のコピペ。

2022/01/10に公開2

経緯

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です。
https://github.com/hiroshu-diary/random_color/blob/main/lib/model.dart

model.dart
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と合わせると、ランダム色を出してコピーできるアプリになります。
https://github.com/hiroshu-diary/random_color/blob/main/lib/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})が使えます。これが最もスマートだと思います。