iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 30
0
Mobile Development

Flutter App 開發實戰系列 第 30

客製功能 | 顯示模式 [Day 30]

  • 分享至 

  • xImage
  •  

編輯完成後使用者可能需要顯示正常的樣子,去除掉網格與灰背景和增加按鈕實際被點擊時該執行什麼動作。


改變狀態

增加 Frame 的狀態有編輯跟預覽模式,FrameDelegate 在按鈕點擊時會使用到,帶著 draggableInfo 讓實作的類別知道被點案的是哪筆資料,在建構式中傳入,新增的這兩個屬性,可以讓外部去決定該顯示哪種模式與按鈕點擊後該如何動作。

+ enum FrameStatus {
+   edit,preview  
+ }
+ class FrameDelegate {
+   onPressed(DraggableInfo draggableInfo){}
+ }

class Frame extends StatefulWidget {

+  FrameStatus frameStatus = FrameStatus.edit ;
+  FrameDelegate delegate  ;

  Frame({
    Key key,
+    this.frameStatus,
+    this.delegate
  }):super(key:key) ;

  @override
  State<StatefulWidget> createState() => FrameState() ;
}

更改網格顏色

增加網格的顏色屬性與更改的方法


class SpacePainter extends CustomPainter {
...
...
...
  Color color = Colors.blueGrey  ;
...
  void setColor(Color color ){
    this.color = color  ;
  }

  @override
  void paint(Canvas canvas, Size size) {
    _paint.color = color;
    ...
    ...
    ...
  }
...
...

在預覽模式下我們將 spacePainter.color 設定成白色或是與背景色相同

class FrameState extends State<Frame> {
  @override
  Widget build(BuildContext context) {

    if (widget.frameStatus == FrameStatus.preview){
      spacePainter.setColor(Colors.white);
    }
  ...
  ...
  ...
  //更改背景色
    if (widget.frameStatus == FrameStatus.preview){
      children.insert(0,Positioned.fill(child: Container(color: Colors.white,)));
    }else{
      children.insert(0,Positioned.fill(child: Container(color: Colors.grey,)));
    }
 }

實作 FrameDelegate

class CarSpaceFrame extends StatefulWidget implements FrameDelegate {
  @override
  State<StatefulWidget> createState() {
    return CarSpaceFrameState();
  }

  @override
  onPressed(DraggableInfo draggableInfo) {
    print(draggableInfo.text) ;
  }
}

class CarSpaceFrameState extends State<CarSpaceFrame>{
    ...
    ...
    ...
     @override
  Widget build(BuildContext context) {
  
    return DragTarget<DraggableInfo>(builder: (context,data,_){
        //傳入delegate與目前希望的狀態
        return Frame(
            key: _frameGlobalKey ,
            delegate: widget,
            frameStatus: FrameStatus.preview,) ;
        },
      onAccept: (data){
        setState(() {
          _frameGlobalKey.currentState.addData(data);
        });
      },
    );

完整的 FrameState build ,

class FrameState extends State<Frame> {
...
...
...
 @override
  Widget build(BuildContext context) {

    if (widget.frameStatus == FrameStatus.preview){
      spacePainter.setColor(Colors.white);
    }else{
      spacePainter.setColor(Colors.blueGrey) ;
    }

    final spacePaint = CustomPaint(painter: spacePainter) ;
    List<Widget>  children = List.generate(data.length, (index) {

      var draggableBtn = RaisedButton(
        child: Text(data[index].text) ,
        onPressed: (){
          //raiseButton 在 onPressed 時執行 delegate 的方法傳入 info data 
          if(widget.frameStatus == FrameStatus.preview)//預覽模式時才可執行
            widget.delegate.onPressed(data[index]);
        },
      );
      Rect rect = fixRect(context, data[index]) ;

      rect = againstPosition(data[index], rect) ;
      print("Rect:$rect.size");

      return Positioned.fromRect(
          rect: rect ,
          child: draggableBtn
      );
    });
    children.insert(0,spacePaint) ;

    if (widget.frameStatus == FrameStatus.preview){
      children.insert(0,Positioned.fill(child: Container(color: Colors.white,)));
    }else{
      children.insert(0,Positioned.fill(child: Container(color: Colors.grey,)));
    }

    
    return Stack(
      fit: StackFit.expand,
      children:children,
    ) ;
  }
  ...
  ...
  ...

範例圖示
https://ithelp.ithome.com.tw/upload/images/20200930/20130127Zdu43lmxD8.png
按下按扭1、2、3時
https://ithelp.ithome.com.tw/upload/images/20200930/201301277iSa5cEg6Q.png


完賽心得

終於寫完了,一開始覺得自己會半途而廢,沒想到最後還是成功結束 30 天不中斷發文,雖然最後這禮拜一直專注在這個編輯按鈕位置的功能上,發文的內容也變比較少,但還是很感謝來看文章的各位,因為覺得每天還是會有人看所以才能持續的寫到最後,很可惜的是 app 沒能在這次挑戰中完成,因為內容太多了,這兩個禮拜公司也特別忙碌每天都加班到好晚,沒時間寫自己的東西了啦,希望下次還能夠有機會跟大家分享自己正在做的產品與應用,這次經驗也讓我有更多成長,學會好好管理時間與如何更好的敘述文檔,看了很多人的文章,覺得很多人都很認真準備的感覺,每次自己發文總會覺得內容準備不夠或是不夠充實,這也是以前自己每次寫文章時會犯的錯,覺得內容太少就不發了,這次最重要的經驗是讓我知道要與瑕疵共存,如果一直不去做就不知道會有什麼改變。恭喜自己結束了我要去好好睡個覺了~

Everyone who’s ever taken a shower has had an idea, It’s the person who gets out of the shower, dries off, and does something about it who makes a difference.
-Nolan Bushnell


上一篇
客製功能 | 按鈕大小 [Day 29]
系列文
Flutter App 開發實戰30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Jason Hung
iT邦新手 2 級 ‧ 2020-10-15 08:49:02

恭喜完賽 ya!!

Leo iT邦新手 5 級 ‧ 2020-10-15 09:41:47 檢舉

感謝~
也恭喜你完賽,你的文章內容都很有趣,之後有機會可以多交流

我要留言

立即登入留言