0

Does anybody knows a right way to hide and show Bottomnavigationbar with animation with correspondence to miniplayer height? As shown in the Fig.1, Bottomnavigationbar shows the overflow warning on bottom only during animation.

enter image description here

Fig.1 A overflow warning is shown during animation.

main.dart

import 'package:flutter/material.dart';
import 'screens/audio_screen.dart';
import 'widgets/player.dart';
import 'utils.dart';

ValueNotifier<AudioObject> currentlyPlaying = ValueNotifier(null);

const double playerMinHeight = 70;
const double playerMaxHeight = 370;
const miniplayerPercentageDeclaration = 0.2;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Miniplayer Demo',
      theme: ThemeData(
        primaryColor: Colors.grey[50],
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
      debugShowCheckedModeBanner: false,
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          Column(
            children: [
              AppBar(
                title: Text('Miniplayer Demo'),
              ),
              Expanded(
                child: AudioUi(
                  onTap: (audioObject) {
                    currentlyPlaying.value = audioObject;
                  },
                ),
              ),
            ],
          ),
          ValueListenableBuilder(
              valueListenable: currentlyPlaying,
              builder: (BuildContext context, AudioObject audioObject,
                  Widget child) {
                if (audioObject == null) return Container();
                return DetailedPlayer(audioObject: audioObject);
              }),
        ],
      ),
      bottomNavigationBar: ValueListenableBuilder(
        valueListenable: playerExpandProgress,
        child: BottomNavigationBar(
          items: <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.home),
              label: 'Feed',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.library_books),
              label: 'Library',
            ),
          ],
          currentIndex: 0,
          selectedItemColor: Colors.blue,
          onTap: (index) {},
        ),
        builder: (BuildContext context, double height, Widget child) {
          final value = percentageFromValueInRange(
              min: playerMinHeight, max: playerMaxHeight, value: height);

          if (value == null) return child;
          var opacity = 1 - value;
          if (opacity < 0) opacity = 0;
          if (opacity > 1) opacity = 1;

          return SizedBox(
            height: kBottomNavigationBarHeight * (1 - value),
            child: Transform.translate(
              offset: Offset(0.0, kBottomNavigationBarHeight * value * 0.5),
              child: Opacity(
                opacity: opacity,
                child: child,
              ),
            ),
          );
        },
      ),
    );
  }
}

pubspec.yaml

name: miniplayer_example
description: A new Flutter project.

publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1

environment:
  sdk: ">=2.7.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter

  google_fonts: ^1.1.1
  miniplayer: ^0.6.1

dev_dependencies:
  flutter_test:
    sdk: flutter

flutter:
  uses-material-design: true

Exception

Performing hot reload...                                                
Reloaded 0 libraries in 633ms.

══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY
╞═════════════════════════════════════════════════════════
The following assertion was thrown during layout:
A RenderFlex overflowed by 3.2 pixels on the bottom.

The relevant error-causing widget was:
  BottomNavigationBar file:///***/lib/main.dart:65:16

To inspect this widget in Flutter DevTools, visit:
http://127.0.0.1:51487/#/inspector?uri=***

The overflowing RenderFlex has an orientation of Axis.vertical.
The edge of the RenderFlex that is overflowing has been marked in the rendering
with a yellow and
black striped pattern. This is usually caused by the contents being too big for
the RenderFlex.
Consider applying a flex factor (e.g. using an Expanded widget) to force the
children of the
RenderFlex to fit within the available space instead of being sized to their
natural size.
This is considered an error condition because it indicates that there is content
that cannot be
seen. If the content is legitimately bigger than the available space, consider
clipping it with a
ClipRect widget before putting it in the flex, or using a scrollable container
rather than a Flex,
like a ListView.
The specific RenderFlex in question is: RenderFlex#090d7 relayoutBoundary=up10
OVERFLOWING:
  creator: Column ← Padding ← Listener ← RawGestureDetector ← GestureDetector ←
  Semantics ←
    _RawMouseRegion ← MouseRegion ← Semantics ← _FocusMarker ← Focus ←
    _ActionsMarker ← ⋯
  parentData: offset=Offset(0.0, 7.0) (can use size)
  constraints: BoxConstraints(0.0<=w<=205.7, 0.0<=h<=36.8)
  size: Size(205.7, 36.8)
  direction: vertical
  mainAxisAlignment: spaceBetween
  mainAxisSize: min
  crossAxisAlignment: center
  verticalDirection: down
◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤
◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤
════════════════════════════════════════════════════════════════════════════════
════════════════════

Another exception was thrown: A RenderFlex overflowed by 3.2 pixels on the
bottom.

Another exception was thrown: A RenderFlex overflowed by 14 pixels on the
bottom.

Another exception was thrown: A RenderFlex overflowed by 60 pixels on the
bottom.

Another exception was thrown: A RenderFlex overflowed by 86 pixels on the
bottom.

Another exception was thrown: A RenderFlex overflowed by 81 pixels on the
bottom.

Another exception was thrown: A RenderFlex overflowed by 86 pixels on the
bottom.

Another exception was thrown: A RenderFlex overflowed by 60 pixels on the
bottom.

Another exception was thrown: A RenderFlex overflowed by 60 pixels on the
bottom.

Another exception was thrown: A RenderFlex overflowed by 86 pixels on the
bottom.

flutter doctor

❯ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.2.3, on macOS 11.4 20F71 darwin-x64, locale en-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 4.1)
[✓] VS Code (version 1.58.2)
[✓] Connected device (2 available)

• No issues found!

Reference (and source code is from). https://github.com/peterscodee/miniplayer/issues/1

To comment1 Tried FittedBox

          return Container(
            height: kBottomNavigationBarHeight * (1 - value),
            child: FittedBox(
              alignment: Alignment.topCenter,
              fit: BoxFit.fitWidth,
              child: Opacity(opacity: opacity, child: child),
            ),
          );
══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
The following assertion was thrown during performLayout():
RenderFlex children have non-zero flex but incoming width constraints are unbounded.
When a row is in a parent that does not provide a finite width constraint, for example if it is in a
horizontal scrollable, it will try to shrink-wrap its children along the horizontal axis. Setting a
flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining
space in the horizontal direction.
These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child
cannot simultaneously expand to fit its parent.
Consider setting mainAxisSize to MainAxisSize.min and using FlexFit.loose fits for the flexible
children (using Flexible rather than Expanded). This will allow the flexible children to size
themselves to less than the infinite remaining space they would otherwise be forced to take, and
then will cause the RenderFlex to shrink-wrap the children rather than expanding to fit the maximum
constraints provided by the parent.
...
The affected RenderFlex is:
  RenderFlex#c2bfc relayoutBoundary=up10 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE(creator: Row ← DefaultTextStyle ← Builder ← MediaQuery ←
  Padding ← DefaultTextStyle ← AnimatedDefaultTextStyle ← _InkFeatures-[GlobalKey#e4557 ink renderer] ← NotificationListener<LayoutChangedNotification> ←
  CustomPaint ← _ShapeBorderPaint ← Material ← ⋯, parentData: offset=Offset(0.0, 0.0) (can use size), constraints: BoxConstraints(0.0<=w<=Infinity,
  56.0<=h<=Infinity), size: MISSING, direction: horizontal, mainAxisAlignment: spaceBetween, mainAxisSize: max, crossAxisAlignment: center, textDirection:
  ltr, verticalDirection: down)
The creator information is set to:
  Row ← DefaultTextStyle ← Builder ← MediaQuery ← Padding ← DefaultTextStyle ←
  AnimatedDefaultTextStyle ← _InkFeatures-[GlobalKey#e4557 ink renderer] ←
  NotificationListener<LayoutChangedNotification> ← CustomPaint ← _ShapeBorderPaint ← Material ← ⋯
The nearest ancestor providing an unbounded width constraint is: RenderFittedBox#7e087 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE:
  creator: FittedBox ← ConstrainedBox ← Container ← ValueListenableBuilder<double> ← MediaQuery ←
    LayoutId-[<_ScaffoldSlot.bottomNavigationBar>] ← CustomMultiChildLayout ← AnimatedBuilder ←
    DefaultTextStyle ← AnimatedDefaultTextStyle ← _InkFeatures-[GlobalKey#25dea ink renderer] ←
    NotificationListener<LayoutChangedNotification> ← ⋯
  parentData: <none> (can use size)
  constraints: BoxConstraints(w=411.4, h=56.0)
  size: MISSING
  fit: fitWidth
  alignment: Alignment.topCenter
  textDirection: ltr

To comment2

          return Transform.translate(
            offset: Offset(0.0, kBottomNavigationBarHeight * value),
            child: SizedBox(
              child: Opacity(opacity: opacity, child: child),
            ),
          );

Bottomnavigator was hiden but miniplayer doesn't stretch to the bottom.

enter image description here

The overflowing RenderFlex has an orientation of Axis.vertical.
The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and
black striped pattern. This is usually caused by the contents being too big for the RenderFlex.
Consider applying a flex factor (e.g. using an Expanded widget) to force the children of the
RenderFlex to fit within the available space instead of being sized to their natural size.
This is considered an error condition because it indicates that there is content that cannot be
seen. If the content is legitimately bigger than the available space, consider clipping it with a
ClipRect widget before putting it in the flex, or using a scrollable container rather than a Flex,
like a ListView.
The specific RenderFlex in question is: RenderFlex#15a52 relayoutBoundary=up3 OVERFLOWING:
  creator: Column ← Opacity ← Padding ← Expanded ← Column ← DecoratedBox ← ConstrainedBox ← Container
    ← DefaultTextStyle ← AnimatedDefaultTextStyle ← _InkFeatures-[GlobalKey#08473 ink renderer] ←
    NotificationListener<LayoutChangedNotification> ← ⋯
  parentData: <none> (can use size)
  constraints: BoxConstraints(0.0<=w<=345.4, h=82.0)
  size: Size(345.4, 82.0)
  direction: vertical
  mainAxisAlignment: spaceEvenly
  mainAxisSize: max
  crossAxisAlignment: center
  verticalDirection: down
◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤
════════════════════════════════════════════════════════════════════════════════════════════════════

Watanabe.N
  • 1,549
  • 1
  • 14
  • 37
  • once i had this issue and it was solved by wrapping with `FittedBox`, can you share simple code structure? – Md. Yeasin Sheikh Jul 29 '21 at 18:06
  • Sorry I found some variables are missing in above code. ValueNotifier playerExpandProgress listens miniplayer height, and valuelistenablebuilder updates bottomnavigationbar according to playerExpandProgress. – Watanabe.N Jul 29 '21 at 18:18
  • The overflow happens because you are animating the `SizedBox` height to be less than the child height i.e. `BottomNavigationBarItem` height. Hence, you only see 2 overflows just below the icons. You can try keeping the `SizedBox` height constant and translate the entire widget to off the screen (hide it below). In my case, I wanted to raise the `BottomAppBar` widget when the keyboard is displayed so I used `Transform.translate` like you have but with a different offset. You can also take a look at `SizeTransition` widget with an axis alignment of 1. – Calvin Gonsalves Jul 29 '21 at 21:06
  • Thank you all. I tried but couldn't work it. I updated my question. – Watanabe.N Jul 30 '21 at 03:23
  • The miniplayer looks that it is floating because the `Scaffold` widget will not show any content behind the `AppBar` and the `BottomNavigationBar` by default. You could try setting the `extendBody` property to true when the `BottomNavigationBar` translates off the screen. I think this will not "stretch" the miniplayer but it will move it down. – Calvin Gonsalves Jul 30 '21 at 20:51
  • floating is because `body: Stack(HomeScreen(), Miniplayer())`. – Watanabe.N Aug 01 '21 at 00:44
  • Do you know why do I get "two" overflow errors? I don't figure out. – Watanabe.N Aug 01 '21 at 00:45

0 Answers0