flutter 非常用組件整理 第二篇

flutter 非常用組件整理 第二篇

視頻

https://youtu.be/fS_4ZxJvaX0

https://www.bilibili.com/video/BV1jS421R7vJ/

前言

原文 https://ducafecat.com/blog/lesser-known-flutter-widgets-02

本文是Flutter非常用組件第二篇塔淤,從開發(fā)者的視角出發(fā),精選并深入剖析了AboutDialog初厚、AnimatedGrid、Badge等鮮為人知卻功能強(qiáng)大的隱藏組件,為讀者提供了一份全面的Flutter UI組件使用指南猪勇。無論您是初學(xué)者還是有經(jīng)驗(yàn)的開發(fā)者,相信本文都能為您的Flutter項(xiàng)目注入新的活力,助力打造出色的應(yīng)用界面棠枉。

Flutter,UI組件,界面設(shè)計(jì),隱藏組件,高級組件,應(yīng)用開發(fā)

參考

正文

AboutDialog

AboutDialog 組件用于顯示應(yīng)用程序的"關(guān)于"對話框浓体。它通常包含應(yīng)用程序的名稱、版本辈讶、版權(quán)信息以及其他相關(guān)細(xì)節(jié)命浴。讓我們來看一個使用 AboutDialog 的例子:

import 'package:flutter/material.dart';

class WidgetPage extends StatefulWidget {
  const WidgetPage({super.key});

  @override
  State<WidgetPage> createState() => _WidgetPageState();
}

class _WidgetPageState extends State<WidgetPage> {
  Widget _mainView() {
    return Center(
      child: Column(
        children: [
          IconButton(
            icon: const Icon(Icons.info),
            onPressed: () {
              showAboutDialog(
                context: context,
                applicationName: '貓哥App',
                applicationVersion: '1.0.0',
                applicationIcon: Image.asset(
                  'assets/app_icon.png',
                  width: 100,
                ),
                applicationLegalese: '? 2024 Ducafecat. All rights reserved.',
              );
            },
          )
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('非常用組件'),
      ),
      body: _mainView(),
    );
  }
}

點(diǎn)擊后可以查看應(yīng)用包使用詳情,還是很有用的贱除。

在這個例子中,我們創(chuàng)建了一個簡單的 Flutter 應(yīng)用程序,包含一個 AppBar 和一個居中的文本生闲。在 AppBar 的操作圖標(biāo)中,我們添加了一個 IconButton,當(dāng)點(diǎn)擊時會顯示 AboutDialog。

showAboutDialog() 函數(shù)用于顯示 AboutDialog月幌。我們?yōu)槠涮峁┝艘韵聦傩?

  • applicationName: 應(yīng)用程序的名稱
  • applicationVersion: 應(yīng)用程序的版本號
  • applicationIcon: 應(yīng)用程序的圖標(biāo)
  • applicationLegalese: 應(yīng)用程序的版權(quán)信息

當(dāng)用戶點(diǎn)擊 AppBar 上的信息圖標(biāo)時,AboutDialog 將顯示應(yīng)用程序的基本信息碍讯。這種對話框通常用于向用戶提供有關(guān)應(yīng)用程序的更多詳細(xì)信息。

AboutListTile

AboutListTile 是一個 ListTile 組件的特殊版本,用于在應(yīng)用程序的設(shè)置或信息頁面上顯示應(yīng)用程序的"關(guān)于"信息扯躺。它結(jié)合了 AboutDialog 的功能,并將其集成到一個可以輕松添加到 ListView 中的 ListTile 小部件中捉兴。

下面是一個使用 AboutListTile 的例子:

import 'package:flutter/material.dart';

class WidgetPage extends StatefulWidget {
  const WidgetPage({super.key});

  @override
  State<WidgetPage> createState() => _WidgetPageState();
}

class _WidgetPageState extends State<WidgetPage> {
  Widget _mainView() {
    return ListView(
      children: [
        AboutListTile(
          icon: Image.asset(
            'assets/app_icon.png',
            width: 100,
          ),
          applicationName: '貓哥App',
          applicationVersion: '1.0.0',
          applicationIcon: Image.asset(
            'assets/app_icon.png',
            width: 100,
          ),
          applicationLegalese: '? 2024 Ducafecat. All rights reserved.',
          aboutBoxChildren: const [
            Text('This is a sample Flutter app.'),
            SizedBox(height: 8.0),
            Text('Developed by My Company.'),
          ],
        ),
        ListTile(
          title: const Text('Privacy Policy'),
          onTap: () {
            // Navigate to privacy policy page
          },
        ),
        ListTile(
          title: const Text('Terms of Service'),
          onTap: () {
            // Navigate to terms of service page
          },
        ),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('非常用組件'),
      ),
      body: _mainView(),
    );
  }
}

點(diǎn)擊后打開版本模式框

在這個例子中蝎困,我們在 SettingsPage 的 ListView 中使用了 AboutListTile 組件。與 AboutDialog 不同倍啥,AboutListTile 直接集成到 ListTile 中,可以輕松地添加到 ListView 中禾乘。

我們?yōu)?AboutListTile 提供了以下屬性:

  • icon: 應(yīng)用程序的圖標(biāo)
  • applicationName: 應(yīng)用程序的名稱
  • applicationVersion: 應(yīng)用程序的版本號
  • applicationIcon: 應(yīng)用程序的圖標(biāo) (與 icon 屬性不同)
  • applicationLegalese: 應(yīng)用程序的版權(quán)信息
  • aboutBoxChildren: 可以添加到 AboutDialog 中的額外 Widget

當(dāng)用戶點(diǎn)擊 AboutListTile 時,它會彈出一個 AboutDialog虽缕,其中包含應(yīng)用程序的基本信息和自定義的 aboutBoxChildren 部分始藕。

這種方式可以讓您輕松地在設(shè)置頁面或信息頁面中添加應(yīng)用程序的"關(guān)于"信息,為用戶提供更好的體驗(yàn)。

AnimatedGrid

AnimatedGrid 是 Flutter 提供的一個強(qiáng)大的組件,用于創(chuàng)建可滾動的網(wǎng)格布局,并在添加氮趋、刪除或重新排序項(xiàng)目時提供動畫效果鳄虱。它通常用于構(gòu)建動態(tài)和交互性強(qiáng)的列表或網(wǎng)格界面。

下面是一個使用 AnimatedGrid 的示例:

import 'package:flutter/material.dart';

class WidgetPage extends StatefulWidget {
  const WidgetPage({super.key});

  @override
  State<WidgetPage> createState() => _WidgetPageState();
}

class _WidgetPageState extends State<WidgetPage> {
  final GlobalKey<AnimatedGridState> _gridKey = GlobalKey();
  final List<int> _items = [];

  void _addItem() {
    int index = _items.length;
    _items.add(index);
    _gridKey.currentState?.insertItem(index);
  }

  void _removeItem(int index) {
    if (index >= 0 && index < _items.length) {
      _gridKey.currentState?.removeItem(
        index,
        (_, animation) => _buildItem(index, animation),
      );
      _items.removeAt(index);
    }
  }

  Widget _buildItem(int item, Animation<double> animation) {
    return ScaleTransition(
      scale: animation,
      child: GestureDetector(
        onDoubleTap: () => _removeItem(item),
        child: Container(
          margin: const EdgeInsets.all(8.0),
          color: Colors.blue,
          child: Center(
            child: Text(
              '$item',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ),
        ),
      ),
    );
  }

  Widget _mainView() {
    return AnimatedGrid(
      key: _gridKey,
      initialItemCount: _items.length,
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 3,
        mainAxisSpacing: 8.0,
        crossAxisSpacing: 8.0,
      ),
      itemBuilder: (context, index, animation) {
        return _buildItem(_items[index], animation);
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('非常用組件'),
        actions: [
          IconButton(
            icon: const Icon(Icons.add),
            onPressed: _addItem,
          ),
        ],
      ),
      body: _mainView(),
    );
  }
}

在這個例子中,我們創(chuàng)建了一個名為 AnimatedGridPage 的頁面,它使用 AnimatedGrid 組件來顯示一個動態(tài)的網(wǎng)格布局凭峡。

AnimatedGrid 組件有以下重要屬性:

  • key: 用于標(biāo)識 AnimatedGrid 實(shí)例,在本例中使用了 GlobalKey<AnimatedGridState> 類型拙已。
  • initialItemCount: 指定初始項(xiàng)目數(shù)量。
  • gridDelegate: 用于配置網(wǎng)格布局,在本例中使用了 SliverGridDelegateWithFixedCrossAxisCount摧冀。
  • itemBuilder: 定義每個網(wǎng)格項(xiàng)的構(gòu)建方式,在本例中使用 _buildItem 方法倍踪。

_addItem_removeItem 方法中,我們分別調(diào)用 insertItemremoveItem 方法來添加和刪除網(wǎng)格項(xiàng)目,同時觸發(fā)相應(yīng)的動畫效果。

_buildItem 方法返回一個 ScaleTransition 組件,它根據(jù)動畫的值來縮放每個網(wǎng)格項(xiàng),從而產(chǎn)生添加或刪除時的動畫效果索昂。

通過使用 AnimatedGrid建车,您可以在 Flutter 應(yīng)用程序中創(chuàng)建動態(tài)且富有交互性的網(wǎng)格布局,并提供平滑的動畫效果。這對于構(gòu)建像聯(lián)系人列表椒惨、圖庫等需要頻繁更新的界面非常有用缤至。

BackButton

BackButton 是一個Flutter 小部件,用于在 Flutter 應(yīng)用程序中添加返回按鈕。它通常用于在應(yīng)用程序的頂部導(dǎo)航欄或應(yīng)用程序頁面的左上角添加一個返回按鈕康谆。當(dāng)用戶點(diǎn)擊這個按鈕時,它會觸發(fā)應(yīng)用程序的導(dǎo)航堆棧進(jìn)行回退领斥。

下面是一個簡單的示例,演示如何在 Flutter 應(yīng)用程序中使用 BackButton:

import 'package:flutter/material.dart';

class BackButtonExample extends StatefulWidget {
  @override
  _BackButtonExampleState createState() => _BackButtonExampleState();
}

class _BackButtonExampleState extends State<BackButtonExample> {
  int _currentPage = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Back Button Example'),
        leading: _currentPage > 0 ? BackButton() : null,
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: _navigateToNextPage,
              child: Text('Go to Next Page'),
            ),
            SizedBox(height: 16.0),
            if (_currentPage > 0)
              ElevatedButton(
                onPressed: _navigateToPreviousPage,
                child: Text('Go to Previous Page'),
              ),
          ],
        ),
      ),
    );
  }

  void _navigateToNextPage() {
    setState(() {
      _currentPage++;
    });
  }

  void _navigateToPreviousPage() {
    setState(() {
      _currentPage--;
    });
  }
}

在這個示例中:

  1. 我們創(chuàng)建了一個 BackButtonExample 頁面,并在 ScaffoldAppBar 中使用了 BackButton 組件。
  2. 我們通過跟蹤 _currentPage 變量來決定是否顯示返回按鈕沃暗。當(dāng) _currentPage 大于 0 時,我們會顯示返回按鈕月洛。
  3. 當(dāng)用戶點(diǎn)擊返回按鈕時,它會觸發(fā)應(yīng)用程序的導(dǎo)航堆棧進(jìn)行回退,從而返回到上一個頁面。
  4. 我們還添加了兩個按鈕,分別用于導(dǎo)航到下一個頁面和上一個頁面孽锥。

通過使用 BackButton嚼黔,您可以在 Flutter 應(yīng)用程序中輕松地添加返回功能,使用戶可以方便地在應(yīng)用程序中導(dǎo)航。這有助于提高應(yīng)用程序的可用性和用戶體驗(yàn)惜辑。

需要注意的是,BackButton 會自動處理設(shè)備上的硬件返回按鈕,并在導(dǎo)航堆棧中進(jìn)行回退唬涧。這可以確保您的應(yīng)用程序在不同設(shè)備上保持一致的行為。

Badge

Badge 是 Flutter 提供的一個小部件,用于在其他小部件上添加一個小的標(biāo)記或標(biāo)識盛撑。這通常用于在應(yīng)用程序的圖標(biāo)或其他用戶界面元素上顯示未讀消息數(shù)量碎节、購物車商品數(shù)量等信息。

下面是一個簡單的示例,演示如何在 Flutter 應(yīng)用程序中使用 Badge 組件:

import 'package:flutter/material.dart';

class WidgetPage extends StatefulWidget {
  const WidgetPage({super.key});

  @override
  State<WidgetPage> createState() => _WidgetPageState();
}

class _WidgetPageState extends State<WidgetPage> {
  int _unreadCount = 0;

  Widget _mainView() {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Badge(
            label: Text('$_unreadCount'),
            offset: const Offset(-5, 5),
            child: IconButton(
              icon: const Icon(
                Icons.notifications,
                size: 32,
              ),
              onPressed: () {
                // Handle notification button press
              },
            ),
          ),
          const SizedBox(height: 16.0),
          ElevatedButton(
            onPressed: _incrementUnreadCount,
            child: const Text('Increment Unread Count'),
          ),
        ],
      ),
    );
  }

  void _incrementUnreadCount() {
    setState(() {
      _unreadCount++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('非常用組件'),
      ),
      body: _mainView(),
    );
  }
}

在這個示例中:

  1. 我們創(chuàng)建了一個 BadgeExample 頁面,并在 Center 組件中放置了一個 Badge 和一個 ElevatedButton撵彻。
  2. Badge 組件包裹了一個 IconButton钓株。當(dāng)用戶點(diǎn)擊這個按鈕時,可以執(zhí)行一些操作,例如打開通知列表。
  3. 我們使用 badgeContent 屬性來顯示未讀消息數(shù)量(_unreadCount)陌僵。當(dāng)未讀消息數(shù)量增加時,Badge 組件會更新其外觀,以反映最新的未讀消息數(shù)量轴合。
  4. 我們添加了一個 ElevatedButton,當(dāng)用戶點(diǎn)擊它時,會觸發(fā) _incrementUnreadCount 函數(shù),從而增加未讀消息計(jì)數(shù)碗短。

通過使用 Badge 組件,您可以在應(yīng)用程序的各種用戶界面元素上顯示小標(biāo)記或標(biāo)識,以向用戶提供重要的上下文信息受葛。這有助于提高應(yīng)用程序的可用性和用戶體驗(yàn)。

Badge 組件提供了許多自定義選項(xiàng),如自定義背景顏色偎谁、文本樣式总滩、位置等,您可以根據(jù)需要進(jìn)行調(diào)整,以匹配應(yīng)用程序的設(shè)計(jì)風(fēng)格。

CloseButton

好的,讓我為您介紹一下 Flutter 中的 CloseButton 組件巡雨。

CloseButton 是一個 Flutter 小部件,用于在應(yīng)用程序的用戶界面中添加一個關(guān)閉按鈕闰渔。它通常用于在對話框、模態(tài)頁面或其他類型的彈出窗口的頂部或角落添加一個關(guān)閉按鈕铐望。當(dāng)用戶點(diǎn)擊這個按鈕時,它會關(guān)閉當(dāng)前頁面或?qū)υ捒?并返回到應(yīng)用程序的上一個狀態(tài)冈涧。

下面是一個簡單的示例,演示如何在 Flutter 應(yīng)用程序中使用 CloseButton:

import 'package:flutter/material.dart';

class WidgetPage extends StatefulWidget {
  const WidgetPage({super.key});

  @override
  State<WidgetPage> createState() => _WidgetPageState();
}

class _WidgetPageState extends State<WidgetPage> {
  bool _showModal = false;

  void _showModalBottomSheet() {
    setState(() {
      _showModal = true;
    });
  }

  void _closeModal() {
    setState(() {
      _showModal = false;
    });
  }

  Widget _mainView() {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ElevatedButton(
            onPressed: _showModalBottomSheet,
            child: const Text('Show Modal'),
          ),
          if (_showModal)
            Container(
              height: 300,
              color: Colors.white,
              child: Stack(
                children: [
                  Positioned(
                    top: 8,
                    right: 8,
                    child: CloseButton(
                      onPressed: _closeModal,
                    ),
                  ),
                  Center(
                    child: Text(
                      'This is a modal window',
                      style: Theme.of(context).textTheme.headlineSmall,
                    ),
                  ),
                ],
              ),
            ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('非常用組件'),
      ),
      body: _mainView(),
    );
  }
}

在這個示例中:

  1. 我們創(chuàng)建了一個 CloseButtonExample 頁面,并在 Scaffoldbody 中放置了一個 ElevatedButton 和一個可選的模態(tài)窗口。
  2. 當(dāng)用戶點(diǎn)擊 "Show Modal" 按鈕時,我們會設(shè)置 _showModal 變量為 true正蛙,從而顯示模態(tài)窗口督弓。
  3. 在模態(tài)窗口的右上角,我們使用了 CloseButton 組件。當(dāng)用戶點(diǎn)擊這個按鈕時,它會調(diào)用 _closeModal 函數(shù),將 _showModal 變量設(shè)置為 false乒验,從而關(guān)閉模態(tài)窗口愚隧。

通過使用 CloseButton,您可以在應(yīng)用程序的各種模態(tài)頁面或彈出窗口中添加一個標(biāo)準(zhǔn)的關(guān)閉按鈕锻全。這有助于提高應(yīng)用程序的一致性和可用性,讓用戶能夠輕松地關(guān)閉不需要的頁面或窗口狂塘。

CloseButton 組件提供了一些自定義選項(xiàng),如自定義圖標(biāo)和顏色,您可以根據(jù)需要進(jìn)行調(diào)整,以匹配應(yīng)用程序的設(shè)計(jì)風(fēng)格。

CustomSingleChildLayout

CustomSingleChildLayout 是一個強(qiáng)大的 Flutter 小部件,它允許您自定義單個子小部件的布局鳄厌。與其他布局小部件不同,CustomSingleChildLayout 不使用預(yù)定義的布局規(guī)則,而是提供了一個回調(diào)函數(shù),您可以在其中實(shí)現(xiàn)自己的布局邏輯睹耐。這使您可以創(chuàng)建復(fù)雜的、動態(tài)變化的用戶界面元素,并將其集成到更廣泛的應(yīng)用程序布局中部翘。

下面是一個示例,演示如何使用 CustomSingleChildLayout 來創(chuàng)建一個自定義的浮動按鈕:

import 'package:flutter/material.dart';

class FloatingButtonLayout extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Custom Single Child Layout'),
      ),
      body: Stack(
        children: [
          // Your main content goes here
          Container(
            color: Colors.grey[200],
            child: Center(
              child: Text('Scroll to see the floating button'),
            ),
          ),
          CustomSingleChildLayout(
            delegate: _FloatingButtonLayoutDelegate(),
            child: ElevatedButton(
              onPressed: () {
                // Handle floating button press
              },
              child: Icon(Icons.add),
            ),
          ),
        ],
      ),
    );
  }
}

class _FloatingButtonLayoutDelegate extends SingleChildLayoutDelegate {
  @override
  Size getSize(BoxConstraints constraints) {
    return Size(60, 60);
  }

  @override
  Offset getPositionForChild(Size size, Size childSize) {
    return Offset(size.width - childSize.width - 16, size.height - childSize.height - 16);
  }

  @override
  bool shouldRelayout(covariant SingleChildLayoutDelegate oldDelegate) {
    return false;
  }
}

在這個示例中:

  1. 我們創(chuàng)建了一個 FloatingButtonLayout 小部件,它包含了一個 Scaffold 和一個 Stack硝训。
  2. Stack 中,我們添加了一個填充頁面的 Container,并在其上放置了一個 CustomSingleChildLayout新思。
  3. CustomSingleChildLayout 使用了一個自定義的 _FloatingButtonLayoutDelegate窖梁,它實(shí)現(xiàn)了三個關(guān)鍵方法:
    • getSize: 返回浮動按鈕的大小。
    • getPositionForChild: 根據(jù)頁面大小和按鈕大小計(jì)算按鈕的位置夹囚。在這個例子中,我們將它放在右下角纵刘。
    • shouldRelayout: 返回 false,因?yàn)檫@個布局不需要重新計(jì)算荸哟。
  4. 最后,我們在 CustomSingleChildLayout 中放置了一個 ElevatedButton假哎,作為浮動按鈕瞬捕。

通過使用 CustomSingleChildLayout,您可以創(chuàng)建各種自定義的布局效果,如浮動按鈕舵抹、懸浮菜單肪虎、自定義對話框等。這為您提供了更大的靈活性和控制權(quán),以滿足應(yīng)用程序的特定需求惧蛹。

CustomSingleChildLayout 的主要優(yōu)點(diǎn)是它允許您完全控制子小部件的布局,而不受其他布局小部件的約束扇救。但同時也需要您編寫更多的自定義代碼來實(shí)現(xiàn)所需的布局邏輯。

Directionality

Directionality 是一個非常有用的 Flutter 小部件,它可以幫助您管理應(yīng)用程序中的文本方向香嗓。在某些情況下,您的應(yīng)用程序可能需要支持從右到左(RTL)或從左到右(LTR)的文本方向,這取決于用戶的語言和區(qū)域設(shè)置迅腔。

Directionality 組件可以為其子小部件提供文本方向信息,從而使它們能夠正確地呈現(xiàn)和布局內(nèi)容靠娱。這對于支持國際化和本地化非常重要,因?yàn)椴煌恼Z言可能需要不同的文本方向沧烈。

下面是一個示例,展示如何使用 Directionality 來創(chuàng)建一個簡單的 RTL 和 LTR 切換器:

import 'package:flutter/material.dart';

class WidgetPage extends StatefulWidget {
  const WidgetPage({super.key});

  @override
  State<WidgetPage> createState() => _WidgetPageState();
}

class _WidgetPageState extends State<WidgetPage> {
  TextDirection _textDirection = TextDirection.ltr;

  Widget _mainView() {
    return Directionality(
      textDirection: _textDirection,
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text('This is some text.'),
            const SizedBox(height: 16.0),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: () {
                    setState(() {
                      _textDirection = TextDirection.ltr;
                    });
                  },
                  child: const Text('Left to Right'),
                ),
                const SizedBox(width: 16.0),
                ElevatedButton(
                  onPressed: () {
                    setState(() {
                      _textDirection = TextDirection.rtl;
                    });
                  },
                  child: const Text('Right to Left'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('非常用組件'),
      ),
      body: _mainView(),
    );
  }
}

在這個示例中:

  1. 我們創(chuàng)建了一個 MyApp 小部件,它包含了一個 Scaffold
  2. Scaffoldbody 中,我們使用了一個 Directionality 小部件。
  3. DirectionalitytextDirection 屬性設(shè)置為 _textDirection柬泽,這是一個 TextDirection 類型的狀態(tài)變量。
  4. Directionality 的子小部件中,我們放置了一個 Text 小部件和兩個切換按鈕嫁蛇。
  5. 當(dāng)用戶點(diǎn)擊"Left to Right"或"Right to Left"按鈕時,我們會更新 _textDirection 狀態(tài)變量的值,從而改變文本方向锨并。

通過使用 Directionality,您可以確保您的應(yīng)用程序中的文本和布局正確地適應(yīng)用戶的語言和區(qū)域設(shè)置睬棚。這對于提高應(yīng)用程序的可訪問性和國際化非常重要第煮。

Directionality 組件還可以嵌套使用,以便為應(yīng)用程序的特定部分設(shè)置不同的文本方向。這使您可以在同一個應(yīng)用程序中混合使用 RTL 和 LTR 文本,并確保它們都能正確顯示抑党。

EditableText

好的,讓我為您介紹一下 Flutter 中的 EditableText 組件包警。

EditableText 是 Flutter 框架提供的一個強(qiáng)大的小部件,用于創(chuàng)建可編輯的文本輸入框。它提供了許多有用的功能,如光標(biāo)控制底靠、選擇和剪切/復(fù)制/粘貼操作害晦。

下面是一個示例,展示如何使用 EditableText 來創(chuàng)建一個簡單的文本編輯器:

import 'dart:ui';

import 'package:flutter/material.dart';

class WidgetPage extends StatefulWidget {
  const WidgetPage({super.key});

  @override
  State<WidgetPage> createState() => _WidgetPageState();
}

class _WidgetPageState extends State<WidgetPage> {
  final TextEditingController _controller = TextEditingController();

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  Widget _mainView() {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: EditableText(
        controller: _controller,
        focusNode: FocusNode(),
        style: const TextStyle(
          fontSize: 18,
          color: Colors.black,
        ),
        cursorColor: Colors.blue,
        backgroundCursorColor: Colors.yellow,
        onChanged: (text) {
          // Handle text changes
          print('Text changed: $text');
        },
        onSubmitted: (text) {
          // Handle text submission
          print('Text submitted: $text');
        },
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('非常用組件'),
      ),
      body: _mainView(),
    );
  }
}

在這個示例中:

  1. 我們創(chuàng)建了一個 MyApp 小部件,它包含了一個 Scaffold
  2. Scaffoldbody 中,我們使用了一個 EditableText 小部件暑中。
  3. EditableTextcontroller 屬性用于管理文本內(nèi)容壹瘟。在這個例子中,我們創(chuàng)建了一個 TextEditingController 實(shí)例并將其傳遞給 EditableText鲫剿。
  4. focusNode 屬性用于管理文本輸入框的焦點(diǎn)狀態(tài)。在這個例子中,我們創(chuàng)建了一個新的 FocusNode 實(shí)例稻轨。
  5. style 屬性用于設(shè)置文本的樣式,例如字體大小和顏色灵莲。
  6. cursorColorbackgroundCursorColor 屬性用于設(shè)置光標(biāo)的顏色。
  7. onChangedonSubmitted 回調(diào)函數(shù)用于在文本發(fā)生變化或提交時執(zhí)行自定義操作澄者。

當(dāng)用戶與 EditableText 交互時,如輸入、選擇请琳、剪切/復(fù)制/粘貼等操作,EditableText 會自動處理這些事件并更新文本內(nèi)容粱挡。您可以通過 controller 屬性訪問和操作文本內(nèi)容,并使用各種回調(diào)函數(shù)來監(jiān)聽和響應(yīng)用戶的輸入。

EditableText 還提供了許多其他屬性,如 obscureText(用于實(shí)現(xiàn)密碼輸入框)俄精、maxLinesmaxLength(用于控制輸入長度)等询筏。這些屬性可以根據(jù)您的具體需求進(jìn)行配置。

小結(jié)

本文從Flutter框架的視角,精選并介紹了幾款鮮為人知卻功能強(qiáng)大的UI組件,幫助開發(fā)者打造更優(yōu)質(zhì)的應(yīng)用界面竖慧。包括AboutDialog嫌套、AnimatedGrid、Badge等隱藏寶藏,為您的Flutter項(xiàng)目注入新活力圾旨。

感謝閱讀本文

如果有什么建議踱讨,請?jiān)谠u論中讓我知道。我很樂意改進(jìn)砍的。


flutter 學(xué)習(xí)路徑


? 貓哥
ducafecat.com

end

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市廓鞠,隨后出現(xiàn)的幾起案子帚稠,更是在濱河造成了極大的恐慌,老刑警劉巖床佳,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滋早,死亡現(xiàn)場離奇詭異,居然都是意外死亡砌们,警方通過查閱死者的電腦和手機(jī)杆麸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來浪感,“玉大人角溃,你說我怎么就攤上這事±撼牛” “怎么了减细?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長赢笨。 經(jīng)常有香客問我未蝌,道長驮吱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任萧吠,我火速辦了婚禮左冬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘纸型。我一直安慰自己拇砰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布狰腌。 她就那樣靜靜地躺著除破,像睡著了一般。 火紅的嫁衣襯著肌膚如雪琼腔。 梳的紋絲不亂的頭發(fā)上瑰枫,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機(jī)與錄音丹莲,去河邊找鬼光坝。 笑死,一個胖子當(dāng)著我的面吹牛甥材,可吹牛的內(nèi)容都是我干的盯另。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼洲赵,長吁一口氣:“原來是場噩夢啊……” “哼土铺!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起板鬓,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤悲敷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后俭令,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體后德,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年抄腔,在試婚紗的時候發(fā)現(xiàn)自己被綠了瓢湃。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡赫蛇,死狀恐怖绵患,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情悟耘,我是刑警寧澤落蝙,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響筏勒,放射性物質(zhì)發(fā)生泄漏移迫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一管行、第九天 我趴在偏房一處隱蔽的房頂上張望厨埋。 院中可真熱鬧,春花似錦捐顷、人聲如沸荡陷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽废赞。三九已至,卻和暖如春逗柴,著一層夾襖步出監(jiān)牢的瞬間蛹头,已是汗流浹背顿肺。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工戏溺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人屠尊。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓旷祸,卻偏偏與公主長得像,于是被迫代替她去往敵國和親讼昆。 傳聞我的和親對象是個殘疾皇子托享,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容