簡體   English   中英

肘的state怎么改?

[英]How to change state of cubit?

圖片說明在這里

當我單擊按鈕時,我想在 4 秒后更改 state 的肘,但它給出了錯誤:

**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**

我的代碼在這里:

主要.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();
}

您在錯誤的 scope 中使用了 BlocProvider,請嘗試將 BlocProvider 移出 MyHomePage class

試試這個:

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')
                )
              ],
            )
        )
    );
  }
}

你有兩種方法可以做到這一點。 首先請記住, BlocProvider.of只會找到小部件樹頂部的 bloc object。 您將TestBloc()放在對等小部件中。 您附加的小部件TestBloc()應該覆蓋您使用BlocProvider.of的地方

**重要:**但我更喜歡另一種方式,因為它很容易理解

聲明var testBloc=TestBloc(); 在 widgetState class 內部的構建方法之外。然后使用testBloc.someMethod BlocProvider.of 不要忘記把它也放在這里:

BlocProvider(
   create: (_) => testCubit,

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM