Виджет стека и конструктор блоков

#flutter #dart #bloc

#flutter #dart #блок

Вопрос:

Я знаю Stack , что виджеты отображают своих дочерних элементов с нуля, однако я не мог объяснить себе, почему a BlocBuilder не может их эффективно перестроить.

Вот пример:

 @override
Widget build(BuildContext context) {
  return Container(
    child: BlocBuilder<TestCubit, int>(
      builder: (context, state) {
        return GestureDetector(
          onTapDown: (tapDetails) {
            context.read<TestCubit>().incrementCubit();
          },
          child: Stack(children: [Text('Counter: $state')]),
        );
      },
    )
  );
}
  

Когда TestCubit incrementCubit вызывается его метод, состояние изменяется — я тестировал его с помощью простого Container пользовательского интерфейса, но как только мы имеем дело со стеком, на экране ничего не происходит. Есть идеи?

Заранее спасибо!

Ответ №1:

Я протестировал ваш код, и он работает как со стеком, так и с контейнером. Пожалуйста, посмотрите мой код ниже :

main.dart

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

void main() {
  runApp(
    const CounterApp(),
  );
}

class CounterApp extends MaterialApp {
  const CounterApp({Key key}) : super(key: key, home: const CounterPage());
}

class CounterPage extends StatelessWidget {
  const CounterPage({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (_) => TestCubit(),
      child: CounterView(),
    );
  }
}

class CounterView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(child: BlocBuilder<TestCubit, int>(
      builder: (context, state) {
        return GestureDetector(
          onTapDown: (tapDetails) {
            context.read<TestCubit>().incrementCubit();
          },
          child: Stack(children: [Text('Counter: $state')]),
          //child: Text('Counter: $state'),
          //child: Scaffold(
          //   appBar: AppBar(title: const Text("Cubit Demo")),
          //   body: Center(
          //       child: Stack(
          //     children: [
          //       Text('Counter: $state'),
          //     ],
          //   )),
          //),
        );
      },
    ));
  }
}

class TestCubit extends Cubit<int> {
  TestCubit() : super(0);
  void incrementCubit() => emit(state   1);
  void decrementCubit() => emit(state - 1);
}
  

pubspec.yaml

 name: test_http
description: A new Flutter application.

publish_to: 'none'

version: 1.0.0 1

environment:
  sdk: ">=2.7.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  flutter_bloc:

dev_dependencies:
  flutter_test:
    sdk: flutter

flutter:
  uses-material-design: true
  

Комментарии:

1. привет, bluenile, спасибо, что взглянули на это! Вы правы, проблема не в виджете стека. На самом деле, до сих пор мне удалось отследить проблему до CustomPaint, которая, похоже, не перестраивается в моем реальном варианте использования. Звучит знакомо?

2. … оказалось, что у CustomPainter для переопределения shouldRepaint установлено значение false… Глупая ошибка, которую я знаю 🙂 Еще раз спасибо!

3. Пожалуйста, примите ответ, если он помог вам решить вашу проблему. Спасибо.