felangel / bloc

A predictable state management library that helps implement the BLoC design pattern
https://bloclibrary.dev
MIT License
11.84k stars 3.4k forks source link

fix: BlocBuilder automatically builds itself when keyboard appear or disappar which causes slow scrolling or rendering issue in Single child scroll view #4051

Closed Abdulah-butt closed 9 months ago

Abdulah-butt commented 9 months ago
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:stepup/presentation/pages/main/create_post/widgets/create_post_media_widget.dart';
import 'package:stepup/presentation/pages/main/create_post/widgets/tag_chip.dart';
import 'package:stepup/presentation/widgets/category_list_widget.dart';
import 'package:stepup/presentation/widgets/custom_appbar.dart';
import 'package:stepup/presentation/widgets/custom_radio_button.dart';
import 'package:stepup/presentation/widgets/custom_safe_area.dart';
import 'package:stepup/presentation/widgets/custom_textfield.dart';
import 'package:stepup/util/app_assets.dart';
import 'package:stepup/util/app_constant.dart';
import 'package:stepup/util/app_style.dart';
import 'create_post_cubit.dart';
import 'create_post_initial_params.dart';
import 'create_post_state.dart';

class CreatePostPage extends StatefulWidget {
  final CreatePostCubit cubit;

  const CreatePostPage({
    Key? key,
    required this.cubit,
  }) : super(key: key);

  @override
  State<CreatePostPage> createState() => _CreatePostState();
}

class _CreatePostState extends State<CreatePostPage> {
  CreatePostCubit get cubit => widget.cubit;

  @override
  void initState() {
    super.initState();
    cubit.navigator.context = context;
  }

  @override
  Widget build(BuildContext context) {
    return CustomSafeArea(
      child: Scaffold(
        appBar: const CustomAppBar(
          titleText: "Create Post",
        ),
        body: SingleChildScrollView(
          child: BlocBuilder<CreatePostCubit, CreatePostState>(
              bloc: cubit,
              builder: (context, state) {
                debugPrint("hello g build called");
                return Padding(
                  padding: AppConstant.screenPadding,
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      SizedBox(
                        height: 10.h,
                      ),
                      Text(
                        "Select Categories",
                        style: AppStyle.createPostHeadingStyle(context),
                      ),
                      SizedBox(
                        height: 18.h,
                      ),
                      CategoryListWidget(
                        categories: cubit.categories,
                        onSelectCategory: (category) {
                          debugPrint("Selected category : ${category}");
                        },
                      ),
                      Padding(
                        padding: EdgeInsets.symmetric(vertical: 12.h),
                        child: const Divider(
                          thickness: 1,
                          height: 0,
                        ),
                      ),
                      CustomTextField(
                        controller: cubit.txtMainTitle,
                        hint: " e.g How to change car tire",
                        label: "Main title",
                        bottomPadding: 0,
                      ),

                      /// horizontal media files
                      SizedBox(
                        height: 193.h,
                        child: ListView.builder(
                          itemCount: 5,
                          scrollDirection: Axis.horizontal,
                          itemBuilder: (context, index) {
                            return CreatePostMediaWidget(
                              isSelected: state.selectedMediaIndex == index,
                              onTap: () {
                                cubit.changeMediaSelection(index);
                              },
                            );
                          },
                        ),
                      ),
                      SizedBox(
                        height: 10.h,
                      ),
                      CustomTextField(
                        controller: cubit.txtStepTitle,
                        hint: "Enter title",
                        label: "Step ${state.selectedMediaIndex + 1} title",
                      ),
                      CustomTextField(
                        controller: cubit.txtStepDescription,
                        hint: "Enter description....",
                        label:
                            "Step ${state.selectedMediaIndex + 1} Description",
                        isDetail: true,
                      ),
                      Text(
                        "Who can see your post?",
                        style: AppStyle.textFieldLabelStyle(context),
                      ),
                      SizedBox(
                        height: 8.h,
                      ),
                      Wrap(
                        children: [
                          for (var privacy in cubit.postPrivacyList)
                            CustomRadioButtonWithText(
                              onChanged: (val) {
                                cubit.updatePostPrivacy(privacy);
                              },
                              isSelected: privacy == state.whoCanSeeThisPost,
                              text: privacy,
                            ),
                        ],
                      ),
                      SizedBox(
                        height: 15.h,
                      ),
                      CustomTextField(
                        controller: cubit.txtTag,
                        hint: "Enter tags",
                        label: "Tags (max 5)",
                        suffixPath: AppAssets.addText,
                        suffixColor: Theme.of(context).colorScheme.primary,
                        suffixAction: cubit.addTag,
                        onSubmit: (val) {
                          cubit.addTag();
                        },
                        inputFormatters: [
                          FilteringTextInputFormatter.deny(RegExp(r'\s')),
                        ],
                        bottomPadding: 10.h,
                      ),

                      /// selected tags
                      Wrap(
                        children: [
                          for (var tag in state.postTags)
                            TagChip(
                                tag: tag,
                                onRemove: () {
                                  cubit.removeTag(tag);
                                }),
                        ],
                      ),
                      SizedBox(
                        height: 20.h,
                      ),
                    ],
                  ),
                );
              }),
        ),
      ),
    );
  }
}
felangel commented 9 months ago

Hi @Abdulah-butt thanks for opening an issue! When you open/close the keyboard the rest of the view is resizing which causes the widgets to rebuild. In this case the parent of the BlocBuilder is rebuilt which causes the BlocBuilder to be rebuilt. This is working as expected and doesn’t have anything to do with flutter_bloc. If you’re running into performance issues then I recommend profiling the app to see what’s causing them.

Hope that helps! 👍

Abdulah-butt commented 9 months ago

I just checked, the parent is not rebuilding, it's BlocBuilder which is building it's self.

felangel commented 9 months ago

I just checked, the parent is not rebuilding, it's BlocBuilder which is building it's self.

Can you share a link to a minimal reproduction sample? Thanks!

felangel commented 9 months ago

Closing for now since it's very difficult for me to help without a link to a minimal reproduction sample. If you feel this is still an issue, feel free to comment with a link to a reproduction sample and I'm happy to take a closer look 👍