flutter_joon_flat 1.0.1 copy "flutter_joon_flat: ^1.0.1" to clipboard
flutter_joon_flat: ^1.0.1 copied to clipboard

Flutter Widget 扁平化扩展库:把嵌套的 widget 树转成链式调用。

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_joon_flat/flutter_joon_flat.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'flutter_joon_flat 示例',
      theme: ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true),
      home: const DemoPage(),
    );
  }
}

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

  @override
  State<DemoPage> createState() => _DemoPageState();
}

class _DemoPageState extends State<DemoPage> {
  bool _toggle = true;
  bool _hasError = false;
  int _tapCount = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('flutter_joon_flat 全模块示例'),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          _section('核心链式', _coreChain()),
          _section('1. layout — 布局', _layoutSection()),
          _section('2. decoration — 装饰', _decorationSection()),
          _section('3. gesture — 手势', _gestureSection()),
          _section('4. visibility — 可见性', _visibilitySection()),
          _section('5. transform — 变换', _transformSection()),
          _section('6. interactive — 交互', _interactiveSection()),
          _section('7. conditional — 条件链', _conditionalSection()),
        ],
      ),
    );
  }

  Widget _section(String title, Widget content) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Padding(
          padding: const EdgeInsets.only(top: 24, bottom: 8),
          child: Text(title, style: Theme.of(context).textTheme.titleMedium?.copyWith(color: Colors.deepPurple)),
        ),
        content,
      ],
    );
  }

  /// 核心示例:Text('Hi').p(16).bg(Colors.white).onTap(() {}).center()
  Widget _coreChain() {
    return const Text('Hi')
        .p(16)
        .bg(Colors.white)
        .rounded(JoonRadius.lg)
        .onTap(() => setState(() => _tapCount++))
        .center();
  }

  /// layout: p, px, py, align, center, size, expanded, safeArea
  Widget _layoutSection() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const Text('p(12)').p(12).bg(Colors.blue.shade100).roundedMd(),
        const SizedBox(height: 8),
        const Text('px(20) py(8)').px(20).py(8).bg(Colors.green.shade100).roundedMd(),
        const SizedBox(height: 8),
        const Text('center()').p(8).bg(Colors.orange.shade100).center(),
        const SizedBox(height: 8),
        const Text('align(Alignment.centerRight)').p(8).bg(Colors.purple.shade100).align(Alignment.centerRight),
        const SizedBox(height: 8),
        const Text('size(200, 40)').size(width: 200, height: 40).bg(Colors.teal.shade100).center(),
        const SizedBox(height: 8),
        Row(
          children: [
            const Text('expanded').p(8).bg(Colors.indigo.shade100).expanded(),
            4.ww,
            const Text('flex:2').p(8).bg(Colors.pink.shade100).expanded(2),
          ],
        ),
        const SizedBox(height: 8),
        Row(children: [const Text('8.ww'), 8.ww, const Text('间距'), 10.ww, const Text('10.hw↓')]),
        10.hw,
        const Text('10.hw 上方间距').p(4),
      ],
    );
  }

  /// decoration: bg, rounded, shadow, clip, card
  Widget _decorationSection() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const Text('bg + roundedLg').p(12).bg(Colors.amber.shade200).roundedLg(),
        const SizedBox(height: 8),
        const Text('roundedXl + shadowLg').p(12).bg(Colors.white).roundedXl().shadowLg(),
        const SizedBox(height: 8),
        const Text('clipCircle').p(16).bg(Colors.cyan).clipCircle(),
        const SizedBox(height: 8),
        const Text('card()').p(16).card(color: Colors.white, shapeRadius: 8),
      ],
    );
  }

  /// gesture: onTap, onLongPress
  Widget _gestureSection() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text('onTap (点击计数: $_tapCount)')
            .p(12)
            .bg(Colors.blue.shade200)
            .roundedLg()
            .onTap(() => setState(() => _tapCount++)),
        const SizedBox(height: 8),
        const Text('onLongPress 长按试试')
            .p(12)
            .bg(Colors.orange.shade200)
            .roundedLg()
            .onLongPress(() => ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('长按触发')))),
      ],
    );
  }

  /// visibility: opacity, visible, offstage, showIf
  Widget _visibilitySection() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const Text('opacity(0.6)').p(12).bg(Colors.green.shade200).opacity(0.6),
        const SizedBox(height: 8),
        Row(
          children: [
            const Text('showIf(_toggle)').p(8).bg(Colors.purple.shade200).showIf(_toggle),
            const SizedBox(width: 8),
            TextButton(
              onPressed: () => setState(() => _toggle = !_toggle),
              child: Text(_toggle ? '隐藏' : '显示'),
            ),
          ],
        ),
        const SizedBox(height: 8),
        const Text('visible(false) 占位隐藏').p(8).bg(Colors.grey.shade300).visible(false),
      ],
    );
  }

  /// transform: rotate, scale, translate, flip
  Widget _transformSection() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const Text('rotate(0.1)').p(8).bg(Colors.amber.shade200).rotate(0.1),
        const SizedBox(height: 8),
        const Text('scale(1.2)').p(8).bg(Colors.teal.shade200).scale(1.2),
        const SizedBox(height: 8),
        const Text('translate(20, 0)').p(8).bg(Colors.indigo.shade200).translate(20, 0),
        const SizedBox(height: 8),
        const Text('flipX()').p(8).bg(Colors.pink.shade200).flipX(),
      ],
    );
  }

  /// interactive: semantics(无 Material 依赖)
  Widget _interactiveSection() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const Text('semantics(label)').p(12).bg(Colors.blue.shade100).semantics(label: '示例标签'),
        const SizedBox(height: 8),
        const Text('semantics(button: true)').p(12).bg(Colors.green.shade100).roundedLg().semantics(button: true, label: '按钮'),
      ],
    );
  }

  /// conditional: when, branch, apply
  Widget _conditionalSection() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        const Text('when(_toggle, 加绿底)')
            .p(8)
            .when(_toggle, (w) => w.bg(Colors.green.shade200))
            .rounded(4),
        const SizedBox(height: 8),
        Row(
          children: [
            const Text('branch(错误?)').p(8).branch(_hasError, (w) => w.bg(Colors.red.shade200), (w) => w.bg(Colors.blue.shade200)).roundedMd(),
            const SizedBox(width: 8),
            TextButton(
              onPressed: () => setState(() => _hasError = !_hasError),
              child: Text(_hasError ? '正常' : '错误'),
            ),
          ],
        ),
        const SizedBox(height: 8),
        const Text('apply((w) => w.p(4).bg(grey))')
            .apply((w) => w.p(4).bg(Colors.grey.shade300))
            .roundedMd(),
      ],
    );
  }
}
1
likes
140
points
26
downloads

Documentation

API reference

Publisher

verified publisherpub.ygjoon.cn

Weekly Downloads

Flutter Widget 扁平化扩展库:把嵌套的 widget 树转成链式调用。

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter

More

Packages that depend on flutter_joon_flat