Flutter未来风格UI插件futuristic的使用

发布于 1周前 作者 ionicwang 来自 Flutter

Flutter未来风格UI插件futuristic的使用

问题

在Flutter中,FutureBuilder widget在StatelessWidget中使用时,每次重建都会重新执行其Future。这可能在非幂等REST API调用中是不可接受的。如何解决这个问题?

解决方案

Futuristic插件提供了一种方法来安全地执行和重试Future,而无需每次都重建StatefulWidget

使用示例

按钮示例
import 'package:flutter/material.dart';
import 'package:futuristic/futuristic.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: const Home(),
      routes: {
        GoodScreen.routeName: (_) => const GoodScreen(),
        BadScreen.routeName: (_) => const BadScreen(),
      },
    );
  }
}

/// A future that completes successfully.
Future<int> goodFuture(int first, int second) async {
  await Future.delayed(const Duration(seconds: 1));
  return first + second;
}

// A future that completes with an exception.
Future<int> badFuture(int first, int second) async {
  await Future.delayed(const Duration(seconds: 1));
  throw Exception('Something happened');
}

class Home extends StatelessWidget {
  const Home({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            SizedBox(height: 50, child: Center(child: GoodButton())),
            SizedBox(height: 50, child: Center(child: BadButton())),
            TextButton(
              child: const Text('Good screen example'),
              onPressed: () {
                Navigator.of(context).pushNamed(GoodScreen.routeName);
              },
            ),
            TextButton(
              child: const Text('Bad screen example'),
              onPressed: () {
                Navigator.of(context).pushNamed(BadScreen.routeName);
              },
            )
          ],
        ),
      ),
    );
  }
}

class GoodButton extends StatelessWidget {
  const GoodButton({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Futuristic<int>(
      futureBuilder: () =&gt; goodFuture(1, 2),
      initialBuilder: (_, start) =&gt; TextButton(onPressed: start, child: const Text('Good button example')),
      busyBuilder: (_) =&gt; const CircularProgressIndicator(),
      dataBuilder: (_, data) =&gt; Text(data.toString()),
    );
  }
}

class BadButton extends StatelessWidget {
  const BadButton({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Futuristic<int>(
      futureBuilder: () =&gt; badFuture(1, 2),
      initialBuilder: (_, start) =&gt; TextButton(onPressed: start, child: const Text('Bad button example')),
      busyBuilder: (_) =&gt; const CircularProgressIndicator(),
      errorBuilder: (_, error, retry) =&gt; TextButton(onPressed: retry, child: const Text('Sorry! Try again')),
    );
  }
}

class GoodScreen extends StatelessWidget {
  static const routeName = '/good';

  const GoodScreen({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Good screen')),
      body: Center(
        child: Futuristic<int>(
          autoStart: true,
          futureBuilder: () =&gt; goodFuture(1, 2),
          busyBuilder: (_) =&gt; const CircularProgressIndicator(),
          dataBuilder: (_, data) =&gt; Text('Data is $data'),
        ),
      ),
    );
  }
}

class BadScreen extends StatelessWidget {
  static const routeName = '/bad';

  const BadScreen({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Bad screen')),
      body: Center(
        child: Futuristic<int>(
          autoStart: true,
          futureBuilder: () =&gt; badFuture(1, 2),
          busyBuilder: (_) =&gt; const CircularProgressIndicator(),
          onError: (error, retry) async {
            await showDialog(
              context: context,
              builder: (innerContext) {
                return AlertDialog(
                  content: const Text('Sorry! Try again'),
                  actions: &lt;Widget&gt;[
                    TextButton(
                      child: const Text('RETRY'),
                      onPressed: () {
                        Navigator.of(innerContext).pop();
                        retry();
                      },
                    )
                  ],
                );
              },
            );
          },
        ),
      ),
    );
  }
}

更多关于Flutter未来风格UI插件futuristic的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter未来风格UI插件futuristic的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用futuristic_ui插件的示例代码。请注意,futuristic_ui是一个假设的插件名称,因为在实际环境中可能没有这样一个具体命名的插件。但我会根据“未来风格UI”的概念,展示如何构建一个具有未来感的UI界面,并会假设有一个类似的插件或自行实现相关组件。

首先,确保你的Flutter项目已经创建,并添加任何必要的依赖项(如果有一个具体的futuristic_ui插件,你需要将其添加到pubspec.yaml文件中)。这里,我将使用Flutter的基础组件和样式来自行实现一个未来风格的UI。

1. 添加依赖项(假设有futuristic_ui插件)

如果有一个具体的futuristic_ui插件,你可以在pubspec.yaml中添加如下依赖:

dependencies:
  flutter:
    sdk: flutter
  futuristic_ui: ^x.y.z  # 替换为实际版本号

然后运行flutter pub get来安装依赖。

2. 创建一个未来风格的UI

以下是一个使用Flutter基础组件创建未来风格UI的示例代码:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Futuristic UI Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        // 自定义一个未来风格的配色方案
        accentColor: Color(0xFF00FFFF), // 青色
        scaffoldBackgroundColor: Color(0xFF202020), // 深灰色背景
        textTheme: TextTheme(
          headline1: TextStyle(
            color: Colors.white,
            fontSize: 32,
            fontWeight: FontWeight.bold,
          ),
          bodyText1: TextStyle(
            color: Colors.lightBlueAccent,
            fontSize: 18,
          ),
        ),
      ),
      home: FuturisticHomePage(),
    );
  }
}

class FuturisticHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Futuristic UI'),
        backgroundColor: Color(0xFF007BFF), // 蓝色背景
        elevation: 0, // 去除阴影
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            // 使用自定义的未来风格按钮
            FuturisticButton(
              label: 'Press Me',
              onPressed: () {
                // 按钮点击事件
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text('Button Pressed!')),
                );
              },
            ),
            SizedBox(height: 20),
            // 使用自定义的未来风格输入框
            FuturisticTextField(
              label: 'Enter Text',
              onSubmitted: (value) {
                // 输入框提交事件
                ScaffoldMessenger.of(context).showSnackBar(
                  SnackBar(content: Text('You typed: $value')),
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}

// 自定义未来风格按钮
class FuturisticButton extends StatelessWidget {
  final String label;
  final VoidCallback onPressed;

  FuturisticButton({required this.label, required this.onPressed});

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      style: ButtonStyle(
        backgroundColor: MaterialStateProperty.all(Color(0xFF00FFFF)), // 青色背景
        shape: MaterialStateProperty.all(
          RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(20),
          ),
        ),
      ),
      onPressed: onPressed,
      child: Text(
        label,
        style: TextStyle(
          color: Colors.black,
          fontSize: 18,
          fontWeight: FontWeight.bold,
        ),
      ),
    );
  }
}

// 自定义未来风格输入框
class FuturisticTextField extends StatelessWidget {
  final String label;
  final ValueChanged<String> onSubmitted;

  FuturisticTextField({required this.label, required this.onSubmitted});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
      child: TextField(
        decoration: InputDecoration(
          labelText: label,
          labelStyle: TextStyle(
            color: Colors.white,
            fontSize: 16,
          ),
          filled: true,
          fillColor: Color(0xFF333333).withOpacity(0.5), // 半透明深灰色填充
          enabledBorder: OutlineInputBorder(
            borderRadius: BorderRadius.circular(20),
            borderSide: BorderSide(color: Colors.transparent),
          ),
          focusedBorder: OutlineInputBorder(
            borderRadius: BorderRadius.circular(20),
            borderSide: BorderSide(color: Color(0xFF00FFFF), width: 2),
          ),
        ),
        onSubmitted: onSubmitted,
        style: TextStyle(
          color: Colors.white,
          fontSize: 16,
        ),
      ),
    );
  }
}

3. 运行项目

将上述代码保存到你的Flutter项目中,并运行flutter run来查看效果。

这个示例展示了如何创建一个具有未来风格的UI,包括自定义的按钮和输入框。如果有一个具体的futuristic_ui插件,你可能只需要引用其提供的组件并按照文档进行配置即可。希望这个示例对你有所帮助!

回到顶部