Home > database >  Flutter SliverAppBar add widget to collapsed part
Flutter SliverAppBar add widget to collapsed part

Time:01-03

I'm currently developing a flutter mobile app by using sliver appbar and I want to add some widget to collapsed app bar.and also make background color to gradient. when I tried to add by using leading property it creates overflow and also the widget displays in the flexspacebar.

enter image description here

The above image is before scroll.

enter image description here

and this one is after scroll and I want to add some widget in the center of the blue part.

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:rehove/Widgets/sliver_card.dart';
import '../Widgets/action_button.dart';
class UserScreen extends StatelessWidget {
  const UserScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    TextTheme _textTheme = Theme.of(context).textTheme;
    return
      AnnotatedRegion<SystemUiOverlayStyle>(
          value: const SystemUiOverlayStyle(
              statusBarColor: Colors.transparent,
              statusBarIconBrightness: Brightness.light

          ),
    child: Scaffold(

      body: CustomScrollView(
        slivers: [
          SliverAppBar(


            collapsedHeight: 320,
            pinned: true,
            leadingWidth: 200,
            leading: Padding(
              padding: EdgeInsets.only(left:32),
              child: GestureDetector(
                onTap:()=>{
                  Navigator.pop(context)
                },
                child: Row(
                  children: [
                    Icon(Icons.arrow_back_ios),
                    Text('Back',style: _textTheme.bodyLarge?.copyWith(
                      fontWeight: FontWeight.w500,
                      fontSize: 16
                    ),)
                  ],
                ),
              ),
            ),
            expandedHeight: 450,
            flexibleSpace: FlexibleSpaceBar(

              background:  Stack(
                children: [
                  Image.asset('assets/images/user.png',
                  width: double.infinity,
                 height: double.infinity,
                 fit: BoxFit.cover,
                ),
                  Align(
                    alignment:Alignment.bottomCenter,
                    child: Container(
                      height: 102,
                      width: double.infinity,
                      color:Color(0xffD9D9D9).withOpacity(0.6),
                      child:Padding(
                        padding:const EdgeInsets.symmetric(horizontal: 20),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            Column(
                              mainAxisAlignment: MainAxisAlignment.center,
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                Text('Liya Dereje',style: _textTheme.bodyLarge?.copyWith(
                                  color: Color(0xffffffff),
                                  fontWeight: FontWeight.w500,
                                  fontSize: 20
                                ),),
                                Text('[email protected]',style: _textTheme.bodyLarge?.copyWith(
                                    color: Color(0xfff7f7f7),
                                    fontWeight: FontWeight.w500,
                                    fontSize: 12
                                ),)
                              ],
                            ),
                           ActionButton(label: 'Edit Profile',
                             height: 38,
                             width: 20,
                             onPressed: () {  },)
                          ],

                        ),
                      )
                    ),
                  )
              ]
              ),
            ),
          ),
           SliverToBoxAdapter(
            child:Column(children:  [
                const SizedBox(height: 40,),
                Row(
                 children:  [
                 const  Expanded(child: Divider(thickness: 1,)),
                   Text('Setting',style: _textTheme.bodySmall?.copyWith(
                     fontSize: 14,
                     fontWeight: FontWeight.w400
                   ),),
                  const Expanded(child: Divider(thickness: 1,)),
                 ],
                ),
                const SizedBox(height: 16,),
                SliverCard(icon: Icons.notifications_outlined,title: 'Notification',amount: '4',),
                const SizedBox(height: 10,),
                SliverCard(icon: Icons.donut_small,title: 'Reports',amount: '4',),
                const SizedBox(height: 10,),
                SliverCard(icon: Icons.email_outlined,title: 'Email',amount: '5',),
                const SizedBox(height: 10,),
                SliverCard(icon: Icons.description_outlined,title: 'Terms of',amount: '3',),
                const SizedBox(height: 10,),
                SliverCard(icon: Icons.accessibility_new_rounded,title: 'Accessibility',amount: '4',),
                const SizedBox(height: 10,),

                SliverCard(icon: Icons.logout,title: 'Logout',amount: '4',),
                const SizedBox(height: 10,),
                SliverCard(icon: Icons.email_outlined,title: 'Email',amount: '5',),
                const SizedBox(height: 10,),
                SliverCard(icon: Icons.description_outlined,title: 'Terms of',amount: '3',),
                const SizedBox(height: 10,),
                SliverCard(icon: Icons.accessibility_new_rounded,title: 'Accessibility',amount: '4',),
                const SizedBox(height: 10,),
              ],
            )

          )
        ],
      ),
    )
    );
  }
}

CodePudding user response:

Add another Stack that wraps your FlexibleSpaceBar and the widget you want in the middle when collapsed. Try this:

flexibleSpace: Stack(
  children: [
    Positioned.fill(
      child: Align(
        alignment: Alignment.center,
        child: Text('I\'m in the center'),
      ),
    ),
    FlexibleSpaceBar(
      background: Stack(children: [
        Image.asset(
          'assets/images/user.png',
          width: double.infinity,
          height: double.infinity,
          fit: BoxFit.cover,
        ),
        Align(
          alignment: Alignment.bottomCenter,
          child: Container(
              height: 102,
              width: double.infinity,
              color: Color(0xffD9D9D9).withOpacity(0.6),
              child: Padding(
                padding:
                    const EdgeInsets.symmetric(horizontal: 20),
                child: Row(
                  mainAxisAlignment:
                      MainAxisAlignment.spaceBetween,
                  children: [
                    Column(
                      mainAxisAlignment:
                          MainAxisAlignment.center,
                      crossAxisAlignment:
                          CrossAxisAlignment.start,
                      children: [
                        Text(
                          'Liya Dereje',
                          style: _textTheme.bodyLarge?.copyWith(
                              color: Color(0xffffffff),
                              fontWeight: FontWeight.w500,
                              fontSize: 20),
                        ),
                        Text(
                          '[email protected]',
                          style: _textTheme.bodyLarge?.copyWith(
                              color: Color(0xfff7f7f7),
                              fontWeight: FontWeight.w500,
                              fontSize: 12),
                        )
                      ],
                    ),
                    ActionButton(
                      label: 'Edit Profile',
                      height: 38,
                      width: 20,
                      onPressed: () {},
                    )
                  ],
                ),
              )),
        )
      ]),
    ),
  ],
),

CodePudding user response:

Step 1: First declare the varibale

bool lastStatus = true;
ScrollController? _nestedScrollController;

Step 2:

void _scrollListener() {
    if (_isShrink != lastStatus) {
      setState(() {
        lastStatus = _isShrink;
      });
    }
  }

  bool get _isShrink {
    return _nestedScrollController != null &&
        _nestedScrollController!.hasClients &&
        _nestedScrollController!.offset > (30.h - kToolbarHeight);
  }

put above method inside the class

Step 3:

 @override
  void dispose() {
    _nestedScrollController?.removeListener(_scrollListener);
    _nestedScrollController?.dispose();
    super.dispose();
  }



 @override
  void initState() {
_nestedScrollController =
        ScrollController(initialScrollOffset: 33.h - kToolbarHeight)
          ..addListener(_scrollListener);

}

Put the above method inside the init and dispose

Step 4:

Scaffold(
            resizeToAvoidBottomInset: false,
              body: NestedScrollView(
              controller: _nestedScrollController,
              headerSliverBuilder: (context, innerBoxIsScrolled) {
                return [
                  TransitionsAppsBar(
         isShrink: _isShrink,

                   ….
            …
                  ),
                ];
              },
              body:  child…      

Step 5: Use require code inside the below class

class TransitionsAppsBar extends StatelessWidget {
  final bool isShrink;
  final VoidCallback? onBackTap;
  final VoidCallback? onInfoTap;
  final VoidCallback? onTap;
  final VoidCallback onAlertTap;
  final GroupDetailsDTO? groupInfo;
  final bool isOverDue;

  const TransitionsAppsBar({
    Key? key,
    this.isShrink = true,
    this.onBackTap,
    this.onInfoTap,
    this.groupInfo,
    this.onTap,
    this.isOverDue = false,
    required this.onAlertTap,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<GroupBloc, GroupState>(
      builder: (context, state) {
        return SliverAppBar(
          elevation: 2,
          backgroundColor: AppTheme.secondaryColor,
          pinned: true,
          collapsedHeight: kToolbarHeight   (isOverDue ? 25 : 0),
          centerTitle: true,
          titleSpacing: 0,
          leadingWidth: 21.w,
          automaticallyImplyLeading: false,
          bottom: !isOverDue
              ? null
              : PreferredSize(
                  child: GestureDetector(
                    onTap: onAlertTap,
                    child: Container(
                      color: AppTheme.primaryColor_100,
                      padding: const EdgeInsets.symmetric(vertical: 4),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Image.asset(
                            Assets.icOverdue,
                            height: 20,
                            width: 20,
                            color: AppTheme.whiteColor,
                          ),
                          const SizedBox(width: 4),
                          Text(
                            StringConstants.groupIsInactive,
                            style: Theme.of(context)
                                .textTheme
                                .caption!
                                .copyWith(color: AppTheme.whiteColor),
                          ),
                          const SizedBox(width: 4),
                          Text(
                            StringConstants.learnMore,
                            style:
                                Theme.of(context).textTheme.caption!.copyWith(
                                      color: AppTheme.whiteColor,
                                      decoration: TextDecoration.underline,
                                    ),
                          ),
                        ],
                      ),
                    ),
                  ),
                  preferredSize: const Size.fromHeight(0),
                ),
          title: GestureDetector(
            onTap: onTap,
            child: Visibility(
              visible: isShrink,
              child: Container(
                color: Colors.transparent,
                width: 100.w,
                height: kToolbarHeight,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Row(
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        Flexible(
                          child: Text(
                            groupInfo?.name ?? '',
                            maxLines: 1,
                            overflow: TextOverflow.ellipsis,
                            style:
                                Theme.of(context).textTheme.caption!.copyWith(
                                      fontSize: 14,
                                      color: AppTheme.whiteColor,
                                      overflow: TextOverflow.ellipsis,
                                    ),
                          ),
                        ),
                        if (groupInfo?.isOverdue ?? false) ...[
                          const SizedBox(width: 8),
                          GestureDetector(
                            onTap: onAlertTap,
                            child: Image.asset(
                              Assets.icOverdue,
                              height: 20,
                              width: 20,
                            ),
                          ),
                        ]
                      ],
                    ),
                    if ((groupInfo?.id ?? 0) != 0)
                      Text(
                        "${(groupInfo?.memberDetails.length ?? 0).toString()} ${StringConstants.loopers}",
                        style: Theme.of(context)
                            .textTheme
                            .caption!
                            .copyWith(fontSize: 14, color: AppTheme.whiteColor),
                      )
                    else
                      Container(),
                  ],
                ),
              ),
            ),
          ),
          leading: Stack(
            alignment: Alignment.centerLeft,
            children: [
              Container(
                margin: EdgeInsets.only(left: 5.h),
                child: Visibility(
                  visible: isShrink,
                  child: ((groupInfo?.id ?? 0) != 0)
                      ? ProfilePic(
                          imageUrl: groupInfo?.image,
                          name: (groupInfo?.name.length ?? 0) <= 3 ||
                                  groupInfo!.isIndividualGroup
                              ? groupInfo?.name
                              : groupInfo?.name.characters.take(3).toString(),
                          picType: groupInfo!.isIndividualGroup
                              ? StringConstants.systemGroup
                              : StringConstants.group,
                        )
                      : Container(),
                ),
              ),
              BackButtonWidget(onBackTap: onBackTap),
            ],
          ),
          expandedHeight: 30.h,
          flexibleSpace: FlexibleSpaceBar(
              background: Center(
            child: Visibility(
              visible: !isShrink,
              child: Column(
                children: [
                  Padding(
                    padding: EdgeInsets.only(top: 12.h),
                    child: ((groupInfo?.id ?? 0) != 0)
                        ? ProfilePic(
                            imageUrl: groupInfo?.image,
                            name: (groupInfo?.name.length ?? 0) <= 3 ||
                                    groupInfo!.isIndividualGroup
                                ? groupInfo?.name
                                : groupInfo?.name.characters.take(3).toString(),
                            picType: groupInfo!.isIndividualGroup
                                ? StringConstants.systemGroup
                                : StringConstants.group,
                            sizeMultiplier: 2.5.h,
                          )
                        : Container(),
                  ),
                  SizedBox(height: 2.h),
                  Row(
                    mainAxisSize: MainAxisSize.min,
                    mainAxisAlignment: MainAxisAlignment.center,
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children: [
                      Flexible(
                        child: Padding(
                          padding: const EdgeInsets.only(left: 12),
                          child: Text(
                            groupInfo?.name ?? "",
                            maxLines: 2,
                            style:
                                Theme.of(context).textTheme.subtitle2!.copyWith(
                                      color: AppTheme.whiteColor,
                                      overflow: TextOverflow.ellipsis,
                                    ),
                          ),
                        ),
                      ),
                      if (groupInfo?.isOverdue ?? false)
                        Padding(
                          padding: const EdgeInsets.only(right: 12, left: 8),
                          child: GestureDetector(
                            onTap: onAlertTap,
                            child: Image.asset(
                              Assets.icOverdue,
                              height: 20,
                              width: 20,
                            ),
                          ),
                        )
                      else
                        const SizedBox(width: 12),
                    ],
                  ),
                  const SizedBox(height: 8),
                  Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 12),
                    child: Text(
                      (groupInfo?.memberDetails ?? [])
                          .getMemberNames(groupInfo?.adminId ?? 0),
                      style: Theme.of(context)
                          .textTheme
                          .caption
                          ?.copyWith(color: AppTheme.whiteColor),
                    ),
                  ),
                ],
              ),
            ),
          )),
          actions: [
            Visibility(
              visible: !groupInfo!.isIndividualGroup &&
                  !state.isFetchingGroupDetails,
              child: GestureDetector(
                onTap: onInfoTap,
                child: Padding(
                  padding: const EdgeInsets.only(right: 10),
                  child: Image.asset(
                    Assets.icInfoGroup,
                    height: 25,
                    width: 25,
                    color: AppTheme.whiteColor,
                  ),
                ),
              ),
            )
          ],
        );
      },
    );
  }
}
  • Related