首页 > 解决方案 > Flutter app:根据ApplicationState值隐藏appBar动作

问题描述

我对 Flutter 很陌生,我想我还没有理解 Providers 状态管理背后的所有逻辑。我有以下小部件:

class App extends StatelessWidget {

   List<IconButton> navigationActions(BuildContext context) {
    return
      Consumer<ApplicationState>(builder: (context, appState, _) {
        if (appState.loginState == 'loggedIn') {
          return [IconButton(
            icon: const Icon(Icons.logout),
            tooltip: 'Logout',
            onPressed: () {
              context.read<ApplicationState>().signOut();
           },
          )];
        }
      })
    ;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('FOO'),
        actions: navigationActions(context)
      ),
      body: ListView(
        .........
      )
    )
 }

我想根据在 ApplicationState 中设置的标志loginState显示/隐藏 AppBar 操作

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => ApplicationState(),
      builder: (context, _) => App(),
    ),
  );
}
class ApplicationState extends ChangeNotifier {
  ApplicationState() {
    init();
  }

  String _loginState = 'loggedOut';
  String get loginState => _loginState;
}

我不确定如何实现功能navigationActions。哪个应该是返回类型?由于我没有在 else 分支中返回数据,因此我不确定如何管理该类型。也许有更聪明的解决方案,我还不知道.. 有人曾经用 Providers 实现过类似的逻辑吗?

标签: flutterdartmobile

解决方案


navigationActions必须返回List<IconButton>,但您返回的结果Consumer是 a Widget。您可以使用其他方法获取ApplicationState. 这是执行您想要的示例代码:

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

class ApplicationState extends ChangeNotifier {
  String _loginState = 'loggedIn';
  set loginState(String state) {
    _loginState = state;
  }

  get loginState => _loginState;
  void toggleState() {
    if (loginState == 'loggedIn')
      loginState = 'loggedOut';
    else
      loginState = 'loggedIn';
    notifyListeners();
  }

  void signOut() {}
}

class ActionTest extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => ApplicationState(),
      child: ActionApp(),
    );
  }
}

class ActionApp extends StatelessWidget {
  List<IconButton> navigationActions(BuildContext context) {
    final appState = Provider.of<ApplicationState>(context);
    if (appState.loginState == 'loggedIn') {
      return [
        IconButton(
          icon: const Icon(Icons.logout),
          tooltip: 'Logout',
          onPressed: () {
            appState.signOut();
          },
        )
      ];
    } else {
      return [];
    }
  }

  @override
  Widget build(BuildContext context) {
    final appState = Provider.of<ApplicationState>(context);
    return Scaffold(
      appBar: AppBar(title: Text('FOO'), actions: navigationActions(context)),
      body: Container(),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          appState.toggleState();
        },
        child: Icon(appState.loginState == 'loggedIn'
            ? Icons.toggle_off
            : Icons.toggle_on),
      ),
    );
  }
}

推荐阅读