flutter 如何改变肘的状态?

ecbunoof  于 2022-12-30  发布在  Flutter
关注(0)|答案(2)|浏览(140)

image description here
我想在点击按钮4秒后更改腕尺的状态,但出现错误:

**BlocProvider.of() called with a context that does not contain a TestCubit.
======== Exception caught by gesture ===============================================================
The following assertion was thrown while handling a gesture:
        BlocProvider.of() called with a context that does not contain a TestCubit.
        No ancestor could be found starting from the context that was passed to BlocProvider.of<TestCubit>().
        This can happen if the context you used comes from a widget above the BlocProvider.
        The context used was: MyHomePage(state: _MyHomePageState#ea89e)
        
When the exception was thrown, this was the stack: 
#0      BlocProvider.of (package:flutter_bloc/src/bloc_provider.dart:103:7)
#1      _MyHomePageState.build.<anonymous closure> (package:flutter_cubit/main.dart:58:34)
#2      _InkResponseState.handleTap (package:flutter/src/material/ink_well.dart:1072:21)
#3      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:253:24)
#4      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:627:11)
#5      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:306:5)
#6      BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:239:7)
#7      PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:615:9)
#8      PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:98:12)
#9      PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:143:9)
#10     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:617:13)
#11     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:141:18)
#12     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:127:7)
#13     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:460:19)
#14     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:440:22)
#15     RendererBinding.dispatchEvent (package:flutter/src/rendering/binding.dart:337:11)
#16     GestureBinding._handlePointerEventImmediately (package:flutter/src/gestures/binding.dart:395:7)
#17     GestureBinding.handlePointerEvent (package:flutter/src/gestures/binding.dart:357:5)
#18     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:314:7)
#19     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:295:7)
#20     _invoke1 (dart:ui/hooks.dart:167:13)
#21     PlatformDispatcher._dispatchPointerDataPacket (dart:ui/platform_dispatcher.dart:341:7)
#22     _dispatchPointerDataPacket (dart:ui/hooks.dart:94:31)
Handler: "onTap"
Recognizer: TapGestureRecognizer#97fe2
  debugOwner: GestureDetector
  state: possible
  won arena
  finalPosition: Offset(188.3, 443.5)
  finalLocalPosition: Offset(30.8, 20.5)
  button: 1
  sent tap down**

我的代码:
main.dart

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_cubit/bloc/test_cubit.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Cubit Bloc'),
      ),
      body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              BlocProvider(
                create: (_) => TestCubit(),
                child: BlocBuilder<TestCubit, TestState>(
                  builder: (context, state) {
                    if (state is Loading) {
                      return CircularProgressIndicator();
                    } else
                    if (state is Loaded) {
                      return Text('Loaded');
                    }
                    return Text('Error');
                  },
                ),
              ),
              ElevatedButton(
                  onPressed: () {
                    BlocProvider.of<TestCubit>(context).getData();
                  },
                  child: Text('Click')
              )
            ],
          )
      )
    );
  }
}

测试_腕尺

import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';

part 'test_state.dart';

class TestCubit extends Cubit<TestState> {

  TestCubit() : super(Loading());

  Future<void> getData() async {
    try {
      emit(Loading());
      await Future.delayed(Duration(seconds: 4));
      emit(Loaded());
    } catch (e) {
      emit(ErrorException());
    }
  }
}

测试状态

part of 'test_cubit.dart';

abstract class TestState extends Equatable {
  const TestState();
}

class Loading extends TestState {
  const Loading();
  @override
  // TODO: implement props
  List<Object?> get props => throw UnimplementedError();
}

class Loaded extends TestState {
  const Loaded();

  @override
  // TODO: implement props
  List<Object?> get props => throw UnimplementedError();
}

class ErrorException extends TestState {
  const ErrorException();

  @override
  // TODO: implement props
  List<Object?> get props => throw UnimplementedError();
}
ahy6op9u

ahy6op9u1#

您有两种方法来完成此操作。首先,请不断提醒BlocProvider.of只找到位于小部件树顶部的块对象。您将TestBloc()放在对等小部件中。您附加TestBloc()的小部件应覆盖您使用**BlocProvider的位置。

    • 重要提示:***但我更喜欢另一种方式,因为它很容易理解 *

声明var testBloc=TestBloc();在widgetState类内部的build方法的外部。然后使用testBloc.someMethod代替BlocProvider.of。不要忘记也把它放在这里:

BlocProvider(
   create: (_) => testCubit,
6psbrbz9

6psbrbz92#

您正在错误的作用域中使用BlocProvider,请尝试将BlocProvider移到MyHomePage类之外
试试这个:

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_cubit/bloc/test_cubit.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (context) => TestCubit(),
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: const MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Cubit Bloc'),
        ),
        body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                BlocBuilder<TestCubit, TestState>(
                  builder: (context, state) {
                    if (state is Loading) {
                      return CircularProgressIndicator();
                    } else if (state is Loaded) {
                      return Text('Loaded');
                    }
                    return Text('Error');
                  },
                ),
                ElevatedButton(
                    onPressed: () {
                      BlocProvider.of<TestCubit>(context).getData();
                    },
                    child: Text('Click')
                )
              ],
            )
        )
    );
  }
}

相关问题