flutter 互動式使用者指導,以及如何在佈局中創造一個洞

語言: CN / TW / HK

原文

http://medium.com/litslink/flutter-interactive-user-guidanc-e-or-how-to-make-a-hole-in-layout-d72bf6eb27f9

程式碼

http://github.com/alex-melnyk/flutter_user_guidance

正文

大家好!我想給你看一個有趣的 Flutter 特徵。我們可以建立互動式的使用者指導使用 blending 混合顏色。

這個簡單的技巧可以讓你在應用程式中建立有趣的使用者指南,而不僅僅是一張圖片。它可以真正與動畫等互動。

佈局

首先,要構建覆蓋,您需要將目標頁面的 Scaffold 小部件包裝到 Stack 小部件中,並將 Scaffold 小部件作為第一個專案保留。

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);

    return Stack(
      children: [
        Scaffold(
          appBar: AppBar(
            title: Text('Flutter User Guidance Example'),
            centerTitle: false,
            actions: [
              IconButton(
                icon: Icon(Icons.slideshow),
                onPressed: () => _userGuidanceController.show(),
              ),
            ],
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  'You have pushed the button this many times:',
                ),
                Text(
                  '$_counter',
                  style: theme.textTheme.headline4,
                ),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: _handleFABPressed,
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
        ),
      ],
    );
  }

對於第二個地方,建立一個覆蓋整個腳手架的覆蓋圖,使用一點透明的深/淺背景。Root ColorFiltered 具有混合模式“ source out”,內部 Container 在後臺具有“ destination out”,這允許我們剪下小部件以在 root ColorFiltered 小部件中剪下它們。

        Positioned.fill(
          child: ColorFiltered(
            colorFilter: ColorFilter.mode(
              Colors.black87,
              BlendMode.srcOut,
            ),
            child: Stack(
              children: [
                Positioned.fill(
                  child: Container(
                    decoration: BoxDecoration(
                      color: Colors.black,
                      backgroundBlendMode: BlendMode.dstOut,
                    ),
                  ),
                ),
                Center(
                  child: Container(
                    width: 150,
                    height: 150,
                    color: Colors.white,
                  ),
                ),
              ],
            ),
          ),
        ),

例如,在這個例子中,我們有一個容器,大小為 150x150,顏色為白色,需要混合的顏色,不應該是完全透明的,否則你不會看到它。因此,顏色是需要混合,以瞭解什麼地區剪出來。

使用者指引

當然,您需要新增一些單詞或元素來引導使用者瀏覽指南。在這種情況下,您可以將小部件放在同一個 Stack 中經過過濾的 root ColorFiltered 上。

        Align(
          alignment: Alignment.bottomLeft,
          child: Material(
            color: Colors.transparent,
            child: Container(
              margin: EdgeInsets.only(
                left: 16,
                bottom: 38,
              ),
              padding: EdgeInsets.symmetric(
                horizontal: 16,
                vertical: 8,
              ),
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.circular(5),
              ),
              child: Text(
                'Hello Interactive User Guidance!\n'
                    'Tap on + button to increase the number...'
              ),
            ),
          ),
        ),

請記住,Stack 小部件來自 Scaffold 並且沒有任何 Material 支援,所以用一個 Material 小部件包裝它就足夠了。

這裡有一個完整的例子,如果你把所有這些步驟都做對了,你會看到同樣的圖片。

  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);

    return Stack(
      children: [
        Scaffold(
          appBar: AppBar(
            title: Text('Flutter User Guidance Example'),
            centerTitle: false,
            actions: [
              IconButton(
                icon: Icon(Icons.slideshow),
                onPressed: () => _userGuidanceController.show(),
              ),
            ],
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  'You have pushed the button this many times:',
                ),
                Text(
                  '$_counter',
                  style: theme.textTheme.headline4,
                ),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: _handleFABPressed,
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
        ),
        Positioned.fill(
          child: ColorFiltered(
            colorFilter: ColorFilter.mode(
              Colors.black87,
              BlendMode.srcOut,
            ),
            child: Stack(
              children: [
                Positioned.fill(
                  child: Container(
                    decoration: BoxDecoration(
                      color: Colors.black,
                      backgroundBlendMode: BlendMode.dstOut,
                    ),
                  ),
                ),
                Align(
                  alignment: Alignment.bottomRight,
                  child: Container(
                    margin: EdgeInsets.only(
                      right: 9,
                      bottom: 27,
                    ),
                    width: 70,
                    height: 70,
                    decoration: BoxDecoration(
                      color: Colors.white,
                      shape: BoxShape.circle,
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
        Align(
          alignment: Alignment.bottomLeft,
          child: Material(
            color: Colors.transparent,
            child: Container(
              margin: EdgeInsets.only(
                left: 16,
                bottom: 38,
              ),
              padding: EdgeInsets.symmetric(
                horizontal: 16,
                vertical: 8,
              ),
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.circular(5),
              ),
              child: Text(
                'Hello Interactive User Guidance!\n'
                    'Tap on + button to increase the number...'
              ),
            ),
          ),
        ),
      ],
    );
  }

動畫和步驟

我準備了一個簡單的例子,通過動畫剪輯區域從矩形切換到圓形並移動,從一個指導切換到另一個。只要檢視我的倉庫,就能獲得這種體驗。

完整的專案原始碼可以在 GitHub 上找到。

http://github.com/alex-melnyk/flutter_user_guidance


© 貓哥

http://ducafecat.tech/

http://github.com/ducafecat

往期

開源

GetX Quick Start

http://github.com/ducafecat/getx_quick_start

新聞客戶端

http://github.com/ducafecat/flutter_learn_news

strapi 手冊譯文

http://getstrapi.cn

微信討論群 ducafecat

系列集合

Dart 程式語言基礎

http://space.bilibili.com/404904528/channel/detail?cid=111585

Flutter 零基礎入門

http://space.bilibili.com/404904528/channel/detail?cid=123470

Flutter 實戰從零開始 新聞客戶端

http://space.bilibili.com/404904528/channel/detail?cid=106755

Flutter 元件開發

http://space.bilibili.com/404904528/channel/detail?cid=144262

Flutter 元件開發

http://space.bilibili.com/404904528/channel/detail?cid=144262

Flutter Bloc

http://space.bilibili.com/404904528/channel/detail?cid=177519

Flutter Getx4

http://space.bilibili.com/404904528/channel/detail?cid=177514

Docker Yapi

http://space.bilibili.com/404904528/channel/detail?cid=130578