iT邦幫忙

2024 iThome 鐵人賽

DAY 29
0
Mobile Development

Flutter基礎入門系列 第 29

【Day 29】為Block增添色彩吧!

  • 分享至 

  • xImage
  •  

在安排活動時,很多時候我們都會希望以顏色來區分不同的活動,因此,今天筆者打算為Schedrag的Block新增「顏色」這個property,並在建立頁面增加一個顏色選擇器。本篇中,將使用flex_color_picker作為新增物件時的顏色選擇器。


新增color property

Color API Docs
基本上,我們只需要在Block類別的propeties, constructors,和其子類別的toMap(), toBlock()函式中加入color的設定項目。僅僅是一些簡單的修改,那麼就不再多做說明,直接放更改後的程式碼吧。

abstract class Block

abstract class Block {
  String? name;
  String? category, notes;
  int? id;
  Color color;

  Block() : color = Colors.white;
  Block.name(this.name) : color = Colors.white;
  Block.detail(
      {this.name, this.category, this.notes, this.color = Colors.white});

  Map<String, Object?> toMap();
  Block toBlock(Map<String, Object?> data);
  void setID(int id) {
    this.id = id;
  }
}

class TodoBlock

class TodoBlock extends Block {
  ...

  TodoBlock.detail(
      {super.name,
      super.category,
      super.notes,
      super.color,
      DateTime? estimatedTime,
      DateTime? deadline})
      : super.detail() {...}
  }

  @override
  Map<String, Object?> toMap() {
    return {
      ...
      'color': color.value.toRadixString(16),
    };
  }

  @override
  TodoBlock toBlock(Map<String, Object?> data) {
    return TodoBlock.detail(
      ...
      color: Color(int.parse(data['color'].toString(), radix: 16)),
    );
  }
}

class TimeBlock

class TodoBlock extends Block {
  ...

  TodoBlock.detail(
      {super.name,
      super.category,
      super.notes,
      super.color,
      DateTime? estimatedTime,
      DateTime? deadline})
      : super.detail() {...}
  }

  @override
  Map<String, Object?> toMap() {
    return {
      ...
      'color': color.value.toRadixString(16),
    };
  }

  @override
  TodoBlock toBlock(Map<String, Object?> data) {
    return TodoBlock.detail(
      ...
      color: Color(int.parse(data['color'].toString(), radix: 16)),
    );
  }
}

class TodoBlocksDb

class TodoBlocksDb extends BlocksDb {
  static const String _executeSQL = '''
    id INTEGER PRIMARY KEY,
    name TEXT, category TEXT,
    estimatedTime DATETIME,
    deadline DATETIME,
    notes TEXT, color TEXT
    ''';
  
  ...
}

class TimeBlocksDb

class TimeBlocksDb extends BlocksDb {
  static const String _executeSQL = '''
    id INTEGER PRIMARY KEY,
    name TEXT, category TEXT,
    startTime DATETIME,
    endTime DATETIME,
    notes TEXT, color TEXT
    ''';
  
  ...
}

顏色選擇器:flex_color_picker

flex_color_picker pub.dev
作者有做個線上的試玩程式

作者的使用教學寫的非常明瞭,基本上只需要對範例程式做幾個變數修改就能直接放到程式中了。做出來的結果如下圖:
https://ithelp.ithome.com.tw/upload/images/20241013/201694465mfdseEpZq.png

首先第一步驟是import我們的flex_color_picker:

import 'package:flex_color_picker/flex_color_picker.dart';

接下來,先新增一個Color類別的變數selectedColor,用於儲存使用者所選擇的顏色。要注意,在使用selectedColor前必須先將它初始化哦!

class _EntryFormState extends State<EntryForm> {
  final TodoBlocksDb? db;

  final _formKey = GlobalKey<FormState>();
  final List<TextEditingController> controllers = ... ;
  List<DateTime?> times = List<DateTime?>.filled(2, null);
  
  Color selectedColor = Colors.white;

下一步便是加上選擇顏色的Widget ColorPicker,在此將它包在一個Card之中。

Card(
  elevation: 2,
  child: ColorPicker(
    color: selectedColor,
    onColorChanged: (Color color) =>
        setState(() => selectedColor = color),
    heading: Text("Select color",
        style: Theme.of(context).textTheme.headlineSmall),
    subheading: Text("Select color shade",
        style: Theme.of(context).textTheme.titleSmall),
  ),
)

主要要設定的是color,顏色儲存用的變數,以及onColorChange,在使用者更改選擇的顏色時要做的行動,在此為設定新顏色為selectedColor。
至於heading和subheading是上圖中的文字說明,供使用者知道各區塊的選擇內容為何。

最後,在新增按鈕處為新物件加入剛剛選擇的顏色:

floatingActionButton: FloatingActionButton(
  onPressed: () {
    if (db != null && _formKey.currentState!.validate()) {
      db?.insert(TodoBlock.detail(
          name: controllers[Tags.name.index].text,
          category: controllers[Tags.category.index].text,
          estimatedTime: times[0],
          deadline: times[1],
          notes: controllers[Tags.notes.index].text,
          color: selectedColor));
      Navigator.pop(context);
    }
  },
  child: const Icon(Icons.add),
),

我們的選擇器就完成啦!測試執行後,也可以看到資料庫中表格多了一個color欄位,並且也將剛剛選擇的顏色給加入其中,可看出程式順利的完成執行了。
https://ithelp.ithome.com.tw/upload/images/20241013/20169446XWPOPcsfkv.png

備註:在進行測試前,須先將過去的資料庫檔案給刪除。因過去的版本沒有「顏色」一欄,會造成讀取時的錯誤。


謝謝閱讀到這裡的讀者,明天也會繼續努力更新的!


上一篇
【Day 28】時刻表的使用 - 續篇
下一篇
【Day 30】為方塊加上色彩,並增加點擊編輯的功能
系列文
Flutter基礎入門30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言