Flutter UI状态管理插件uistate的使用

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

Flutter UI状态管理插件uistate的使用

UIState 是一种在 Flutter 小部件中表示 UI 状态的最简洁方法。

界面展示

加载中 成功 失败

使用方法

通过 Provider 获取数据的实时流表示:

UIState<String> state = Provider.of<ViewModel>(context).state;

受到 Kotlin 的内联 switch 启发,when 方法返回当前状态的相应小部件:

state.when(
    success: (event) => Text(event.value),
    failure: (event) => Text('Error: ${event.errorMessage}'),
    loading: (event) => CircularProgressIndicator(),
)

构建方法示例

[@override](/user/override)
Widget build(BuildContext context) {
  UIState<String> state = Provider.of<ViewModel>(context).state;

  return Scaffold(
    body: Container(
      margin: EdgeInsets.all(20),
      child: Center(
        child: state.when(
          success: (event) => Text(event.value),
          failure: (event) => Text('Error: ${event.errorMessage}'),
          loading: (event) => CircularProgressIndicator(),
        ),
      ),
    ),
    floatingActionButton: FloatingActionButton(
      child: Icon(Icons.adjust_sharp),
      onPressed: () {
        Provider.of<ViewModel>(context, listen: false).fetchUser();
      },
    ),
  );
}

ChangeNotifier (ViewModel) 一侧

state 变量将反映数据请求的加载/失败/成功状态:

class ViewModel extends ChangeNotifier {
  final UsernameRepository repository;
  ViewModel(this.repository);

  UIState<String> state = Loading();

  fetchUser() async {
    try {
      String username = await repository.getUsername();
      state = Success(username);
    } catch (error) {
      state = Failure(error.toString());
    }

    notifyListeners();
  }
}

安装

pubspec.yaml 文件中添加依赖项:

flutter pub add uistate

示例代码

以下是完整的示例代码:

import 'package:flutter/material.dart';

import 'package:provider/provider.dart';
import 'package:uistate/uistate.dart';
import 'package:uistate_example/username_repository.dart';
import 'package:uistate_example/viewmodel.dart';

void main() {
  runApp(MultiProvider(providers: [
    ChangeNotifierProvider<ViewModel>.value(value: ViewModel(UsernameRepository())),
  ], child: MyApp()));
}

class MyApp extends StatelessWidget {
  // 这个小部件是你的应用的根
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'UI State 示例',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter 示例首页'),
    );
  }
}

class MyHomePage extends StatelessWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  [@override](/user/override)
  Widget build(BuildContext context) {
    UIState<String> state = Provider.of<ViewModel>(context).state;

    return Scaffold(
      body: Container(
        margin: EdgeInsets.all(20),
        child: Center(
          child: state.when(
            success: (event) => successWidget(event.value),
            failure: (event) => failureWidget(event.errorMessage),
            loading: (event) => loadingSpinner(),
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Provider.of<ViewModel>(context, listen: false).fetchUser();
        },
        tooltip: 'Increment',
        child: Icon(Icons.adjust_sharp),
      ), // 这个尾随逗号使自动格式化更美观
    );
  }

  CircularProgressIndicator loadingSpinner() => CircularProgressIndicator();

  final style = const TextStyle(fontSize: 30, color: Colors.white);

  successWidget(String string) {
    return Container(
      padding: EdgeInsets.all(10),
      color: Colors.green,
      child: Text(string, style: style),
    );
  }

  failureWidget(String string) {
    return Container(
      padding: EdgeInsets.all(10),
      color: Colors.red,
      child: Text(string, style: style),
    );
  }
}

更多关于Flutter UI状态管理插件uistate的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter UI状态管理插件uistate的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,UI状态管理是一个核心话题,而uistate是一个帮助管理UI状态的插件。尽管uistate并不是Flutter官方推荐的状态管理解决方案(如Provider、Riverpod、Bloc等),但它提供了一种简洁的方式来管理UI状态。

以下是一个简单的例子,展示如何在Flutter项目中使用uistate插件来管理UI状态。

1. 添加依赖

首先,你需要在pubspec.yaml文件中添加uistate依赖:

dependencies:
  flutter:
    sdk: flutter
  uistate: ^最新版本号  # 请替换为最新的版本号

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

2. 创建UIState类

接下来,你需要创建一个继承自UIState的类,用于管理你的UI状态。

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

class MyAppState extends UIState<MyAppState> {
  bool isLoading = false;
  String message = '';

  void startLoading() {
    setState(() {
      isLoading = true;
      message = 'Loading...';
    });
  }

  void stopLoading(String resultMessage) {
    setState(() {
      isLoading = false;
      message = resultMessage;
    });
  }
}

3. 使用UIStateWidget

现在,你可以使用UIStateWidget来将你的状态类与UI组件绑定。

import 'package:flutter/material.dart';
import 'package:uistate/uistate.dart';
import 'my_app_state.dart';  // 假设你将状态类放在这个文件中

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return UIStateProvider<MyAppState>(
      initialState: MyAppState(),
      child: MaterialApp(
        home: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final MyAppState state = UIState.of<MyAppState>(context);

    return Scaffold(
      appBar: AppBar(
        title: Text('UIState Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            if (state.isLoading)
              CircularProgressIndicator()
            else
              Text(state.message),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                state.startLoading();
                // 模拟一个异步操作,比如网络请求
                Future.delayed(Duration(seconds: 2), () {
                  state.stopLoading('Data Loaded!');
                });
              },
              child: Text('Load Data'),
            ),
          ],
        ),
      ),
    );
  }
}

解释

  1. MyAppState 类:定义了一个简单的状态类,包含isLoadingmessage两个状态变量,以及两个用于修改这些状态的方法startLoadingstopLoading

  2. MyApp 类:使用UIStateProvider来提供初始状态MyAppState,并将其包装在MaterialApp中。

  3. MyHomePage 类:使用UIState.of<MyAppState>(context)来获取当前的状态实例,并根据isLoading的值显示不同的UI组件(加载指示器或文本)。同时,提供了一个按钮来触发状态的改变。

这个例子展示了如何使用uistate插件来管理UI状态,但请注意,对于更复杂的应用,你可能需要考虑使用更强大的状态管理解决方案,如Provider、Riverpod或Bloc。

回到顶部