【问题标题】:flutter_bloc library increment decrement button using flutter bloc使用flutter bloc的flutter_bloc库递增递减按钮
【发布时间】:2021-11-24 05:50:55
【问题描述】:

我对flutter_bloc库很陌生,我正在尝试制作增量减量按钮的组件,但是当我尝试复制组件时,我遇到了问题,当我按下第二个增量按钮组件时,第一个组件也更新了像这样result。我希望他们有分离的结果。我该如何解决?

这是我的集团代码:

import 'package:bloc/bloc.dart';

abstract class QtyEvent{}

class Increment extends QtyEvent {}

class Decrement extends QtyEvent {}

class QtyBloc extends Bloc<QtyEvent, int> {
  QtyBloc() : super(0) {
    on<Increment>((event, emit) =>
      emit(state+1));
    on<Decrement>((event, emit) =>
      emit(state-1));
  }
}

这是我的组件代码:

class _QtyState extends State<Qty> {
  int _n = 0;
  @override
  void add() {
    setState(() {
      _n++;
    });
    context.read<QtyBloc>().add(Increment());
  }

  void minus() {
    setState(() {
      if (_n != 0) _n--;
    });
    context.read<QtyBloc>().add(Decrement());
  }

  QtyBloc qtybloc = QtyBloc();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),), 
      body: Column(
        children: [
          Row(
            children: [
              GestureDetector(
                onTap: minus,
                child: Container(
                  padding: EdgeInsets.all(5),
                  decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(20),
                      color: Colors.red),
                  child: Icon(Icons.remove),
                ),
              ),
              Text(
                context.watch<QtyBloc>().state.toString(),
                style: TextStyle(fontSize: 20),
              ),
              GestureDetector(
                onTap: add,
                child: Container(
                  padding: EdgeInsets.all(5),
                  decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(20),
                      color: Colors.red),
                  child: Icon(Icons.add),
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

【问题讨论】:

    标签: flutter bloc


    【解决方案1】:

    您的代码完全按照它的设计目的进行。
    如果我理解正确,您想使用同一个 Bloc 来拥有两个 set incrementdecrement 按钮?

    由于您是emitting 一个state,当您在一个地方更新它时,它会在所有地方更新!

    另外,您不需要调用setState,因为它会重新渲染 UI,这可以通过 bloc it self 来实现。

    而且,在您提到的标题中,您使用flutter_bloc,但在您的代码中,您使用的是bloc

    Flutter Bloc

    Bloc

    这里是如何用flutter_bloc实现它,

    logic.dart

    import 'package:flutter_bloc/flutter_bloc.dart';
    
    class CounterEvent {
      const CounterEvent();
    }
    
    class Increment extends CounterEvent {
      final int value1, value2;
      const Increment({this.value1 = 1, this.value2 = 1});
    }
    
    class Decrement extends CounterEvent {
      final int value1, value2;
      const Decrement({this.value1 = 1, this.value2 = 1});
    }
    
    class Reset extends CounterEvent {
      final int value;
      const Reset({this.value = 0});
    }
    
    class CounterState {
      final int s1, s2;                                       // Just maintain 2 values!
      const CounterState({required this.s1, required this.s2});
    }
    
    class CounterBloc extends Bloc<CounterEvent, CounterState> {
      CounterBloc(CounterState initialState) : super(initialState);
    
      @override
      Stream<CounterState> mapEventToState(CounterEvent event) async* {
        if (event is Increment) {
          yield CounterState(
              s1: state.s1 + event.value1, s2: state.s2 + event.value2);
        } else if (event is Decrement) {
          yield CounterState(
              s1: state.s1 - event.value1, s2: state.s2 - event.value2);
        } else if (event is Reset) {
          yield CounterState(s1: event.value, s2: event.value);
        }
      }
    }
    
    

    component_page.dart

    class Component extends StatelessWidget {
      const Component({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Counter'),
          ),
          body: BlocBuilder<CounterBloc, CounterState>(
            builder: (context, state) {
              return Column(
                children: [
                  Row(
                    children: [
                      GestureDetector(
                        onTap: () {
                          BlocProvider.of<CounterBloc>(context)
                              .add(const Decrement(value1: 1, value2: 0));
                        },
                        child: Container(
                          padding: const EdgeInsets.all(5),
                          decoration: BoxDecoration(
                              borderRadius: BorderRadius.circular(20),
                              color: Colors.red),
                          child: const Icon(Icons.remove),
                        ),
                      ),
                      Text(
                        state.s1.toString(),
                        style: const TextStyle(fontSize: 20, color: Colors.white),
                      ),
                      GestureDetector(
                        onTap: () {
                          BlocProvider.of<CounterBloc>(context)
                              .add(const Increment(value1: 1, value2: 0));
                        },
                        child: Container(
                          padding: const EdgeInsets.all(5),
                          decoration: BoxDecoration(
                              borderRadius: BorderRadius.circular(20),
                              color: Colors.red),
                          child: const Icon(Icons.add),
                        ),
                      ),
                    ],
                  ),
                  Row(
                    children: [
                      GestureDetector(
                        onTap: () {
                          BlocProvider.of<CounterBloc>(context)
                              .add(const Decrement(value1: 0, value2: 1));
                        },
                        child: Container(
                          padding: const EdgeInsets.all(5),
                          decoration: BoxDecoration(
                              borderRadius: BorderRadius.circular(20),
                              color: Colors.red),
                          child: const Icon(Icons.remove),
                        ),
                      ),
                      Text(
                        state.s2.toString(),
                        style: const TextStyle(fontSize: 20, color: Colors.white),
                      ),
                      GestureDetector(
                        onTap: () {
                          BlocProvider.of<CounterBloc>(context)
                              .add(const Increment(value1: 0, value2: 1));
                        },
                        child: Container(
                          padding: const EdgeInsets.all(5),
                          decoration: BoxDecoration(
                              borderRadius: BorderRadius.circular(20),
                              color: Colors.red),
                          child: const Icon(Icons.add),
                        ),
                      ),
                    ],
                  ),
                  Row(
                    children: [
                      GestureDetector(
                        onTap: () {
                          BlocProvider.of<CounterBloc>(context)
                              .add(const Reset(value: 0));
                        },
                        child: Container(
                          padding: const EdgeInsets.all(5),
                          decoration: BoxDecoration(
                              borderRadius: BorderRadius.circular(20),
                              color: Colors.red),
                          child: const Icon(Icons.refresh),
                        ),
                      ),
                    ],
                  ),
                ],
              );
            },
          ),
        );
      }
    } 
    

    注意

    • 这段代码是用 null 安全性编写的
    • 记得在您的应用周围添加BlocProvider,如下所示:

    main.dart

    void main() async {
      runApp(const App());
    }
    
    class App extends StatelessWidget {
      const App({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return BlocProvider<CounterBloc>(
          create: (_) => CounterBloc(const CounterState(s1: 0, s2: 0)),
          child: const MaterialApp(
            debugShowCheckedModeBanner: false,
            home: Component(),
          ),
        );
      }
    }
    

    【讨论】:

    • 非常感谢!
    • @RakaPrasetyo 请接受答案
    • 有人可以为 Flutter_bloc 8.0 重构这段代码吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多