如何像SwiftUI一樣在flutter上寫(xiě)UI

在線預(yù)覽
https://dartpad.dev/b6485d75ac2b9ee7e6096df8fce0c0e0

import 'package:flnewpay_core_example/widget_extenstion_modify.dart';
import 'package:flutter/material.dart';

class ChainableExample extends StatelessWidget {
  const ChainableExample({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('鏈?zhǔn)秸{(diào)用示例')),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          _buildSectionTitle('動(dòng)畫(huà)效果'),
          _buildAnimationDemo(),
          _buildSectionTitle('基礎(chǔ)文本樣式'),
          _buildTextDemo(),
          _buildSectionTitle('容器裝飾'),
          _buildContainerDemo(),
          _buildSectionTitle('組合布局'),
          _buildLayoutDemo(),
          _buildSectionTitle('按鈕樣式'),
          _buildButtonDemo(),
          _buildSectionTitle('卡片組件'),
          _buildCardDemo(),
        ],
      ).scrollable().safeArea(),
    );
  }

  Widget _buildSectionTitle(String title) => Text(title)
      .fontSize(14)
      .textColor(Colors.grey)
      .paddingOnly(left: 16, top: 16, bottom: 8);

  Widget _buildTextDemo() => [
    // String 擴(kuò)展快速創(chuàng)建
    '你好木木噠'.text.fontSize(24).bold().textColor(Colors.blue),
    16.vGap,
    // Text 鏈?zhǔn)綐邮?    const Text('下劃線+斜體').underline().italic().textColor(Colors.orange),
    8.vGap,
    const Text('帶陰影文字').fontSize(20).bold().shadow(),
    8.vGap,
    const Text('這是一段很長(zhǎng)的文字需要省略顯示的效果測(cè)試').ellipsis(),
  ].toColumn(crossAxisAlignment: CrossAxisAlignment.start).paddingAll(16);

  Widget _buildContainerDemo() => [
    // 背景+圓角
    const Text(
      '背景+圓角',
    ).paddingAll(12).background(Colors.blue.shade100).cornerRadius(8),
    12.vGap,
    // 漸變背景
    const Text('漸變背景')
        .textColor(Colors.white)
        .paddingAll(12)
        .linearGradient(colors: [Colors.blue, Colors.purple])
        .cornerRadius(8),
    12.vGap,
    // 陰影+邊框
    const Text('陰影+邊框')
        .paddingAll(12)
        .border(color: Colors.blue, width: 2, radius: 8)
        .shadow(blurRadius: 8),
    12.vGap,
    // 模糊效果
    const Text('模糊效果').paddingAll(12).blur(sigmaX: 1, sigmaY: 1),
  ].toColumn(crossAxisAlignment: CrossAxisAlignment.start).paddingAll(16);

  Widget _buildLayoutDemo() =>
      Row(
            children: [
              // 圓形圖標(biāo)
              const Icon(Icons.star, color: Colors.amber, size: 30)
                  .background(Colors.red)
                  .paddingAll(12)
                  .background(Colors.amber.shade50)
                  .circle(),
              12.hGap,
              // 文字?jǐn)U展填充
              const Text('Rating: 4.5').fontSize(16).expanded(),
              // 右側(cè)圖標(biāo)
              const Icon(Icons.arrow_forward_ios, size: 16).opacity(0.5),
            ],
          )
          .paddingAll(16)
          .background(Colors.grey.shade100)
          .cornerRadius(12)
          .margin(const EdgeInsets.symmetric(horizontal: 16));

  Widget _buildButtonDemo() => [
    // 主按鈕
    const Text('主按鈕')
        .fontSize(16)
        .textColor(Colors.white)
        .bold()
        .center()
        .height(48)
        .fullWidth()
        .background(Colors.blue)
        .cornerRadius(24)
        .onTap(() => debugPrint('主按鈕點(diǎn)擊')),
    12.vGap,
    // 次按鈕
    const Text('次按鈕')
        .fontSize(16)
        .textColor(Colors.blue)
        .center()
        .height(48)
        .fullWidth()
        .border(color: Colors.blue, width: 1.5, radius: 24)
        .onTap(() => debugPrint('次按鈕點(diǎn)擊')),
    12.vGap,
    // 禁用按鈕
    const Text('禁用按鈕')
        .fontSize(16)
        .textColor(Colors.grey)
        .center()
        .height(48)
        .fullWidth()
        .background(Colors.grey.shade200)
        .cornerRadius(24)
        .ignorePointer(),
  ].toColumn().paddingSymmetric(horizontal: 16);

  Widget _buildCardDemo() =>
      [
            const Text('卡片標(biāo)題').fontSize(18).bold(),
            8.vGap,
            const Text(
              '這是卡片內(nèi)容描述,支持多行顯示。',
            ).fontSize(14).textColor(Colors.grey.shade600).lines(2),
            16.vGap,
            Row(
              children: [
                const Text('查看詳情').textColor(Colors.blue).expanded(),
                const Icon(Icons.arrow_forward, color: Colors.blue, size: 18),
              ],
            ),
          ]
          .toColumn(crossAxisAlignment: CrossAxisAlignment.start)
          .paddingAll(16)
          .decorated(
            color: Colors.white,
            borderRadius: 12.circular,
            boxShadow: [
              BoxShadow(
                color: Colors.black.withOpacity(0.08),
                blurRadius: 10,
                offset: const Offset(0, 4),
              ),
            ],
          )
          .margin(const EdgeInsets.symmetric(horizontal: 16));

  Widget _buildAnimationDemo() => [
    // 淡入效果 - 自動(dòng)播放
    const Text('淡入(自動(dòng))')
        .paddingAll(12)
        .background(Colors.green.shade100)
        .cornerRadius(8)
        .animate(Anim.fadeIn(duration: const Duration(milliseconds: 500))),
    12.vGap,
    // 從左滑入 - 自動(dòng)播放
    const Text('滑入(自動(dòng))')
        .paddingAll(12)
        .background(Colors.orange.shade100)
        .cornerRadius(8)
        .animate(Anim.slideLeft(delay: const Duration(milliseconds: 200))),
    12.vGap,
    // 彈跳 - 點(diǎn)擊觸發(fā)
    const Text('點(diǎn)擊彈跳')
        .paddingAll(12)
        .background(Colors.purple.shade100)
        .cornerRadius(8)
        .animate(Anim.bounce(trigger: AnimTrigger.onTap)),
    12.vGap,
    // 縮放 - 點(diǎn)擊觸發(fā)
    const Text('點(diǎn)擊縮放')
        .paddingAll(12)
        .background(Colors.blue.shade100)
        .cornerRadius(8)
        .animate(Anim.scale(trigger: AnimTrigger.onTap)),
    12.vGap,
    // 抖動(dòng) - 點(diǎn)擊觸發(fā)
    const Text('點(diǎn)擊抖動(dòng)')
        .paddingAll(12)
        .background(Colors.red.shade100)
        .cornerRadius(8)
        .animate(Anim.shake(trigger: AnimTrigger.onTap)),
    12.vGap,
    // 旋轉(zhuǎn) - 點(diǎn)擊觸發(fā)
    Row(
      children: [
        const Icon(
          Icons.refresh,
          color: Colors.teal,
          size: 40,
        ).animate(Anim.rotate(trigger: AnimTrigger.onTap)),
        12.hGap,
        const Text('點(diǎn)擊旋轉(zhuǎn)').textColor(Colors.grey),
      ],
    ),
    12.vGap,
    // 脈沖循環(huán) - 點(diǎn)擊切換
    Row(
      children: [
        const Icon(
          Icons.favorite,
          color: Colors.red,
          size: 40,
        ).animate(Anim.pulse(repeat: true, trigger: AnimTrigger.onTap)),
        12.hGap,
        const Text('點(diǎn)擊切換脈沖').textColor(Colors.grey),
      ],
    ),
    12.vGap,
    // 閃爍循環(huán) - 點(diǎn)擊切換
    Row(
      children: [
        const Icon(
          Icons.notifications,
          color: Colors.amber,
          size: 40,
        ).animate(Anim.blink(repeat: true, trigger: AnimTrigger.onTap)),
        12.hGap,
        const Text('點(diǎn)擊切換閃爍').textColor(Colors.grey),
      ],
    ).background(Colors.black.withOpacity(0.1)),
    12.vGap,
    // 淡入+滑入組合 - 點(diǎn)擊觸發(fā)
    const Text('點(diǎn)擊淡入滑入')
        .paddingAll(12)
        .background(Colors.cyan.shade100)
        .cornerRadius(8)
        .animate(Anim.fadeSlide(trigger: AnimTrigger.onTap)),
  ].toColumn(crossAxisAlignment: CrossAxisAlignment.start).paddingAll(16);
}

image.png

自用文件很簡(jiǎn)單僅一個(gè)擴(kuò)展日常開(kāi)發(fā)基本夠用
https://pub.dev/packages/flchain_extension

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容