Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
300 views
in Technique[技术] by (71.8m points)

How to approach conditional Icon swapping based on app state using Riverpod in Flutter?

In my custom AppBar.leading I want to display a certain IconButton depending on an app state value using the Riverpod package. This IconButton also conditionally switches depending on the platform. Besides some set-up boilerplate using this example I'm not sure how to continue. I'll show my current state below:

models/flash_status.dart:

enum FlashStatus {
  auto,
  on,
  off,
}

// ignore: missing_return
String flashStatusInStringFormat(FlashStatus flashStatus) {
  switch (flashStatus) {
    case FlashStatus.auto:
      return 'Auto';
    case FlashStatus.on:
      return 'On';
    case FlashStatus.off:
      return 'Off';
  }
}

providers/providers.dart:

import 'package:flutter_riverpod/flutter_riverpod.dart';

import 'package:MyApp/models/flash_status.dart';

final flashStatusProvider = StateProvider((ref) => FlashStatus.auto);

lib/main.dart:

import 'package:flutter_riverpod/flutter_riverpod.dart';

void main() {
  runApp(
    ProviderScope(
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {...

widgets/tool_bar.dart:

import 'dart:io' show Platform;

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

import 'package:MyApp/providers/providers.dart';

class ToolBar extends StatelessWidget with PreferredSizeWidget {
  @override
  final Size preferredSize;

  ToolBar({
    Key key,
  })  : preferredSize = Size.fromHeight(50.0),
        super(key: key);

  IconData get flashIconAuto =>
      Platform.isAndroid ? Icons.flash_auto : CupertinoIcons.bolt_badge_a;

  IconData get flashIconOn =>
      Platform.isAndroid ? Icons.flash_on : CupertinoIcons.bolt_fill;

  IconData get flashIconOff =>
      Platform.isAndroid ? Icons.flash_off : CupertinoIcons.bolt_slash;

  @override
  Widget build(BuildContext context) {
    return AppBar(
      automaticallyImplyLeading: false,
      backgroundColor: Colors.transparent,
      leading: IconButton(
        icon: Icon(flashIconAuto),
        tooltip: 'Turn on camera flash',
        onPressed: () {},
      ),
    );
  }
}

I'm not sure where to go from here, I have to use Consumer to wrap the IconButton right? How do I handle conditionally showing the right icon based on state? Am I missing model methods to update the state? What do the onPressed handlers look like?

question from:https://stackoverflow.com/questions/65851546/how-to-approach-conditional-icon-swapping-based-on-app-state-using-riverpod-in-f

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
    import 'dart:io';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

enum FlashStatus {
  auto,
  on,
  off,
}

final flashStatusProvider = StateProvider((ref) => FlashStatus.auto);

class FlashScreen extends StatefulWidget {
  @override
  _FlashScreenState createState() => _FlashScreenState();
}

class _FlashScreenState extends State<FlashScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: ToolBar(),
    );
  }
}

class ToolBar extends StatelessWidget with PreferredSizeWidget {
  @override
  final Size preferredSize;

  ToolBar({
    Key key,
  })  : preferredSize = Size.fromHeight(50.0),
        super(key: key);

  IconData get flashIconAuto =>
      Platform.isAndroid ? Icons.flash_auto : CupertinoIcons.bolt_badge_a;

  IconData get flashIconOn =>
      Platform.isAndroid ? Icons.flash_on : CupertinoIcons.bolt_fill;

  IconData get flashIconOff =>
      Platform.isAndroid ? Icons.flash_off : CupertinoIcons.bolt_slash;

  @override
  Widget build(BuildContext context) {
    return AppBar(
      automaticallyImplyLeading: false,
      backgroundColor: Colors.transparent,
      leading: Consumer(builder: (context, ScopedReader watch, child) {
        final status = watch(flashStatusProvider);
        print(status.state);
        switch (status.state) {
          case FlashStatus.on:
            return IconButton(
              icon: Icon(flashIconOff),
              tooltip: 'Turn off camera flash',
              onPressed: () =>
                  context.read(flashStatusProvider).state = FlashStatus.off,
            );
            break;
          case FlashStatus.off:
            return IconButton(
                icon: Icon(flashIconOn),
                tooltip: 'Turn on camera flash',
                onPressed: () =>
                    context.read(flashStatusProvider).state = FlashStatus.on);
            break;
          default:
            return IconButton(
                icon: Icon(flashIconOn),
                tooltip: 'Turn on camera flash',
                onPressed: () =>
                    context.read(flashStatusProvider).state = FlashStatus.on);
        }
      }),
    );
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...