简体   繁体   English

Flutter BLoC state 只更新一次

[英]Flutter BLoC state only update once

I'm using flutter_bloc to manage few widgets with MultiBlocProvider, but the bloc I've created only updating state once, in second try and later when I press button to trigger event code in bloc can be executed but cannot update state and cannot to change UI我正在使用 flutter_bloc 来管理带有 MultiBlocProvider 的几个小部件,但是我创建的 bloc 仅更新 state 一次,在第二次尝试和稍后当我按下按钮触发 bloc 中的事件代码时可以执行但无法更新 state 并且无法更改界面

send_billing_screen.dart send_billing_screen.dart

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:siteinspection2contractor/screen/billing/billing_layout.dart';
import 'package:siteinspection2contractor/screen/send_billing/send_billing_layout.dart';
import 'package:siteinspection2contractor/widget/billing_attachment/bloc/billing_attachment_bloc.dart';
import 'package:siteinspection2contractor/widget/send_billing_header/bloc/send_billing_header_bloc.dart';

class SendBillingScreen extends StatefulWidget {
  final int termynId;
  SendBillingScreen({required this.termynId});
  @override
  _SendBillingScreenState createState() => _SendBillingScreenState();
}

class _SendBillingScreenState extends State<SendBillingScreen> {
  SendBillingHeaderBloc _sendBillingHeaderBloc = SendBillingHeaderBloc();
  BillingAttachmentBloc _billingAttachmentBloc = BillingAttachmentBloc();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MultiBlocProvider(
        providers: [
          BlocProvider(
            create: (BuildContext context) => _sendBillingHeaderBloc
          ),
          BlocProvider(
            create: (BuildContext context) => _billingAttachmentBloc,
          ),
      ],
      child: SendBillingLayout(termynId: widget.termynId,)
    );
  }
}

send_billing_layout.dart send_billing_layout.dart

import 'package:flutter/material.dart';
import 'package:siteinspection2contractor/helper/color_palette_helper.dart';
import 'package:siteinspection2contractor/widget/billing_attachment/billing_attachment_widget.dart';
import 'package:siteinspection2contractor/widget/billing_attachment/header_widget.dart';
    
class SendBillingLayout extends StatefulWidget {
  final int termynId;
  SendBillingLayout({required this.termynId});

  @override
  _SendBillingLayoutState createState() => _SendBillingLayoutState();
}

class _SendBillingLayoutState extends State<SendBillingLayout> {
  ColorPaletteHelper colorx = ColorPaletteHelper();
  late String base64KwitansiResult = '';
  late String base64PajakResult = '';
  late String base64BastResult = '';
  var isLoading = false;
  var result = 'Result In Here';

  @override
  Widget build(BuildContext context) {
    Size size = MediaQuery.of(context).size;
    return Scaffold(
      body: SafeArea(
        child: SingleChildScrollView(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              HeaderWidget()
              BillingAttachmentWidget()
            ],
          ),
        )
      ),
    );
  }
}

billing_attachment_widget.dart billing_attachment_widget.dart

import 'dart:io';
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:dotted_border/dotted_border.dart';
import 'package:image_picker/image_picker.dart';
import 'package:siteinspection2contractor/helper/color_palette_helper.dart';
import 'package:siteinspection2contractor/widget/billing_attachment/bloc/billing_attachment_bloc.dart';
import 'package:siteinspection2contractor/helper/color_palette_helper.dart';

class BillingAttachmentWidget extends StatefulWidget {
  @override
  _BillingAttachmentWidgetState createState() => _BillingAttachmentWidgetState();
}

class _BillingAttachmentWidgetState extends State<BillingAttachmentWidget> {
  ColorPaletteHelper colorx = ColorPaletteHelper();

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<BillingAttachmentBloc, BillingAttachmentState>(
        builder: (context, state) {
          if(state is BillingAttachmentInitial) {
            print("--> INITIAL <--");
            return buildFrame(context, '');
          }
          if(state is PhotoPicked) {
            print("--> PHOTO CAPTURED <--");
            return buildFrame(context, state.base64Result);
          } else {
            print("--> NOTHING <--");
            return buildFrame(context, '');
          }

        }
    );
  }

  Widget buildFrame(BuildContext context, String base64Result) {
    Size size = MediaQuery.of(context).size;
    return Column(
      children: [
        Container(
          margin: EdgeInsets.only(left: size.width*0.07, right: size.width*0.07, top: size.width*0.00, ),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text('Billing Attachment', style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold),),
              SizedBox(height: size.height*0.04,),
              Text('Kwitansi Asli', style: TextStyle(fontWeight: FontWeight.bold),),
              SizedBox(height: size.height*0.01,),
              DottedBorder(
                child: base64Result==''?Container(
                    height: size.height*0.25,
                    width: double.maxFinite,
                    color: colorx.holy,
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Text("Please pick photo from gallery or camera", style: TextStyle(fontSize: 12.0),),
                      ],
                    )
                ):
                Image.memory(
                  const Base64Decoder().convert(base64Result),
                  fit: BoxFit.contain,
                ),
              ),
              SizedBox(height: size.width*0.01,),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  ElevatedButton(
                    style: ElevatedButton.styleFrom(
                        primary: Colors.teal,
                        fixedSize: Size.fromWidth(100),
                        padding: EdgeInsets.all(10)
                    ),
                    child: Row(
                      children: [
                        Icon(Icons.camera_alt),
                        Text(' Camera')
                      ],
                    ),
                      onPressed: () =>  context.read<BillingAttachmentBloc>().add(PickPhotoFromCamera())
                  ),
                  SizedBox(width: size.width*0.05,),
                  ElevatedButton(
                      style: ElevatedButton.styleFrom(
                          primary: Colors.teal,
                          fixedSize: Size.fromWidth(100),
                          padding: EdgeInsets.all(10)
                      ),
                      child: Row(
                        children: [
                          Icon(Icons.image),
                          Text(' Gallery')
                        ],
                      ),
                      onPressed: () => context.read<BillingAttachmentBloc>().add(PickPhotoFromGallery())
                  ),
                ],
              ),


            ],
          ),
        ),
      ],
    );
  }
}

billing_attachment_event.dart billing_attachment_event.dart

part of 'billing_attachment_bloc.dart';

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

class PickPhotoFromCamera extends BillingAttachmentEvent {

  @override
  List<Object> get props => [];
}

class PickPhotoFromGallery extends BillingAttachmentEvent {

  @override
  List<Object> get props => [];
}

billing_attachment_bloc.dart billing_attachment_bloc.dart

import 'dart:async';
import 'dart:ui';
import 'dart:io';
import 'dart:convert';
import 'dart:typed_data';

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

import '../../../helper/constant_helper.dart';

part 'billing_attachment_event.dart';
part 'billing_attachment_state.dart';

class BillingAttachmentBloc extends Bloc<BillingAttachmentEvent, BillingAttachmentState> {
  ConstantHelper constant = ConstantHelper();

  BillingAttachmentBloc() : super(BillingAttachmentInitial()) {
    on<PickPhotoFromCamera>((event, emit) async {
      print('--> BILLING BLOC : PICK PHOTO FROM CAMERA <--');
      var pickedFile = await ImagePicker().getImage(source: ImageSource.camera, maxWidth: constant.photoMaxWidth);
      if (pickedFile != null) {
        File imageFile = File(pickedFile.path);
        List<int> imageBytes = imageFile.readAsBytesSync();
        String base64Image = base64Encode(imageBytes);
        emit(PhotoPicked(base64Result: base64Image));
      }

    });

    on<PickPhotoFromGallery>((event, emit) async {
      print('--> BILLING BLOC : PICK PHOTO FROM GALLERY <--');
      var pickedFile = await ImagePicker().getImage(source: ImageSource.gallery, maxWidth: constant.photoMaxWidth);
      if (pickedFile != null) {
        File imageFile = File(pickedFile.path);
        List<int> imageBytes = imageFile.readAsBytesSync();
        String base64Image = base64Encode(imageBytes);
        emit(PhotoPicked(base64Result: base64Image));
      }

    });
  }

  @override
  Stream<BillingAttachmentState> mapEventToState(
    BillingAttachmentEvent event,
  ) async* {
    // TODO: implement mapEventToState
  }
}

billing_attachemnt_state.dart billing_attachemnt_state.dart

part of 'billing_attachment_bloc.dart';

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

class BillingAttachmentInitial extends BillingAttachmentState {
  @override
  List<Object> get props => [];
}

class PhotoPicked extends BillingAttachmentState {
  final String base64Result;
  const PhotoPicked({required this.base64Result});
  @override
  List<Object> get props => [];
}

Try changing尝试改变

class PhotoPicked extends BillingAttachmentState {
  final String base64Result;
  const PhotoPicked({required this.base64Result});
  @override
  List<Object> get props => [];
}

to

class PhotoPicked extends BillingAttachmentState {
  final String base64Result;
  const PhotoPicked({required this.base64Result});
  @override
  List<Object> get props => [base64Result];   // Here is the change
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM