material-components / material-components-flutter-codelabs

Codelabs for Material Components for Flutter
212 stars 247 forks source link

MDC-104 add _BackdropTitle , but error #151

Closed mofada closed 5 years ago

mofada commented 5 years ago

screen

This is my running screenshot, then something went wrong, the problem should be in the dropdrop.dart, I don't know where the error is, guess the width of the leading is not enough

Performing hot restart...
Syncing files to device Android SDK built for x86...
Restarted application in 1,581ms.
I/flutter ( 1007): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 1007): The following message was thrown during layout:
I/flutter ( 1007): A RenderFlex overflowed by 83 pixels on the right.
I/flutter ( 1007): 
I/flutter ( 1007): The overflowing RenderFlex has an orientation of Axis.horizontal.
I/flutter ( 1007): The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and
I/flutter ( 1007): black striped pattern. This is usually caused by the contents being too big for the RenderFlex.
I/flutter ( 1007): Consider applying a flex factor (e.g. using an Expanded widget) to force the children of the
I/flutter ( 1007): RenderFlex to fit within the available space instead of being sized to their natural size.
I/flutter ( 1007): This is considered an error condition because it indicates that there is content that cannot be
I/flutter ( 1007): seen. If the content is legitimately bigger than the available space, consider clipping it with a
I/flutter ( 1007): ClipRect widget before putting it in the flex, or using a scrollable container rather than a Flex,
I/flutter ( 1007): like a ListView.
I/flutter ( 1007): The specific RenderFlex in question is:
I/flutter ( 1007):   RenderFlex#1fe49 OVERFLOWING
I/flutter ( 1007):   creator: Row ← DefaultTextStyle ← _BackdropTitle ← ConstrainedBox ←
I/flutter ( 1007):   LayoutId-[<_ToolbarSlot.leading>] ← CustomMultiChildLayout ← NavigationToolbar ← DefaultTextStyle
I/flutter ( 1007):   ← IconTheme ← Builder ← CustomSingleChildLayout ← ClipRect ← ⋯
I/flutter ( 1007):   parentData: <none> (can use size)
I/flutter ( 1007):   constraints: BoxConstraints(w=56.0, h=56.0)
I/flutter ( 1007):   size: Size(56.0, 56.0)
I/flutter ( 1007):   direction: horizontal
I/flutter ( 1007):   mainAxisAlignment: start
I/flutter ( 1007):   mainAxisSize: max
I/flutter ( 1007):   crossAxisAlignment: center
I/flutter ( 1007):   textDirection: ltr
I/flutter ( 1007):   verticalDirection: down
I/flutter ( 1007): ◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤
I/flutter ( 1007): ════════════════════════════════════════════════════════════════════════════════════════════════════
import 'package:Shrine/login.dart';

/**
 * @author : fada
 * @email : fada@mofada.cn
 * @date : 2019/3/4 22:54
 * @description : input your description
 **/
import 'package:flutter/material.dart';
import 'package:meta/meta.dart';

import 'model/product.dart';

///动画速度
const double _kFlingVelocity = 2.0;

class Backdrop extends StatefulWidget {
  /// 当前分类
  final Category currentCategory;

  ///前面的部件
  final Widget frontLayer;

  ///后面的部件
  final Widget backLayer;

  ///前面的标题
  final Widget frontTitle;

  ///后面的标题
  final Widget backTitle;

  Backdrop(
      {@required this.currentCategory,
      @required this.frontLayer,
      @required this.backLayer,
      @required this.frontTitle,
      @required this.backTitle})
      : assert(currentCategory != null),
        assert(frontLayer != null),
        assert(backLayer != null),
        assert(frontTitle != null),
        assert(backTitle != null);

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

class _BackdropState extends State<Backdrop>
    with SingleTickerProviderStateMixin {
  final GlobalKey _backdropKey = GlobalKey(debugLabel: 'Backdrop');

  ///动画控制类
  AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
        vsync: this, duration: Duration(seconds: 300), value: 1.0);
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  ///关闭前层
  @override
  void didUpdateWidget(Backdrop oldWidget) {
    super.didUpdateWidget(oldWidget);

    if (widget.currentCategory != oldWidget.currentCategory) {
      _toggleBackdropLayerVisibility();
    } else if (!_frontLayerVisible) {
      _controller.fling(velocity: _kFlingVelocity);
    }
  }

  Widget _buildStack(BuildContext context, BoxConstraints contains) {
    const double layerTitleHeight = 48.0;
    final Size layerSize = contains.biggest;
    final double layerTop = layerSize.height - layerTitleHeight;

    Animation<RelativeRect> layerAnimation = RelativeRectTween(
      begin: RelativeRect.fromLTRB(0, layerTop, 0, layerTop - layerSize.height),
      end: RelativeRect.fromLTRB(0, 0, 0, 0),
    ).animate(_controller.view);

    return Stack(
      key: _backdropKey,
      children: <Widget>[
        ExcludeSemantics(
          child: widget.backLayer,
          excluding: _frontLayerVisible,
        ),
        PositionedTransition(
          rect: layerAnimation,
          child: _FrontLayout(
            child: widget.frontLayer,
            onTap: _toggleBackdropLayerVisibility,
          ),
        )
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    var appBar = AppBar(
      brightness: Brightness.light,
      elevation: 0.0,
      titleSpacing: 0.0,
//      leading: IconButton(
//        icon: Icon(Icons.menu),
//        onPressed: _toggleBackdropLayerVisibility,
//      ),
      leading: _BackdropTitle(
        frontTitle: widget.frontTitle,
        backTitle: widget.backTitle,
        listenable: _controller.view,
        onPress: _toggleBackdropLayerVisibility,
      ),
      title: Text('SHRINE'),
      actions: <Widget>[
        IconButton(
            icon: Icon(
              Icons.search,
              semanticLabel: 'search',
            ),
            onPressed: () {
              Navigator.push(
                  context,
                  MaterialPageRoute(
                      builder: (BuildContext context) => LoginPage()));
            }),
        IconButton(
            icon: Icon(
              Icons.tune,
              semanticLabel: 'filter',
            ),
            onPressed: () {
              Navigator.push(
                  context,
                  MaterialPageRoute(
                      builder: (BuildContext context) => LoginPage()));
            })
      ],
    );
    return Scaffold(
      appBar: appBar,
      body: LayoutBuilder(
        builder: _buildStack,
      ),
    );
  }

  ///获取前景是否可见
  bool get _frontLayerVisible {
    final AnimationStatus status = _controller.status;
    return status == AnimationStatus.completed ||
        status == AnimationStatus.forward;
  }

  ///切换可见性
  void _toggleBackdropLayerVisibility() {
    _controller.fling(
        velocity: _frontLayerVisible ? -_kFlingVelocity : _kFlingVelocity);
  }
}

///斜切角的前景
class _FrontLayout extends StatelessWidget {
  const _FrontLayout({Key key, this.child, this.onTap}) : super(key: key);

  final Widget child;
  final VoidCallback onTap;

  @override
  Widget build(BuildContext context) {
    return Material(
      elevation: 16.0,
      shape: BeveledRectangleBorder(
          borderRadius: BorderRadius.only(topLeft: Radius.circular(46))),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: <Widget>[
          GestureDetector(
            behavior: HitTestBehavior.opaque,
            onTap: onTap,
            child: Container(
              height: 40,
              alignment: AlignmentDirectional.center,
            ),
          ),
          Expanded(child: child)
        ],
      ),
    );
  }
}

class _BackdropTitle extends AnimatedWidget {
  final Function onPress;
  final Widget frontTitle;
  final Widget backTitle;

  _BackdropTitle(
      {this.onPress,
      Key key,
      Listenable listenable,
      @required this.frontTitle,
      @required this.backTitle})
      : assert(frontTitle != null),
        assert(backTitle != null),
        super(key: key, listenable: listenable);

  @override
  Widget build(BuildContext context) {
    final Animation<double> animation = this.listenable;

    return DefaultTextStyle(
        style: Theme.of(context).primaryTextTheme.title,
        softWrap: false,
        overflow: TextOverflow.ellipsis,
        child: Row(
          children: <Widget>[
            SizedBox(
              width: 72.0,
              child: IconButton(
                  padding: EdgeInsets.only(right: 8),
                  icon: Stack(
                    children: <Widget>[
                      Opacity(
                        opacity: animation.value,
                        child: ImageIcon(AssetImage('assets/slanted_menu.png')),
                      ),
                      FractionalTranslation(
                        translation: Tween<Offset>(
                                begin: Offset.zero, end: Offset(1.0, 0.0))
                            .evaluate(animation),
                        child: ImageIcon(AssetImage('assets/diamond.png')),
                      )
                    ],
                  ),
                  onPressed: this.onPress),
            ),
            Stack(
              children: <Widget>[
                Opacity(
                  opacity: CurvedAnimation(
                          parent: ReverseAnimation(animation),
                          curve: Interval(0.5, 1.0))
                      .value,
                  child: FractionalTranslation(
                    translation:
                        Tween<Offset>(begin: Offset.zero, end: Offset(0.5, 0.0))
                            .evaluate(animation),
                    child: backTitle,
                  ),
                ),
                Opacity(
                  opacity: CurvedAnimation(
                          parent: animation, curve: Interval(0.5, 1.0))
                      .value,
                  child: FractionalTranslation(
                    translation: Tween<Offset>(
                            begin: Offset(-0.25, 0.0), end: Offset.zero)
                        .evaluate(animation),
                    child: frontTitle,
                  ),
                ),
              ],
            )
          ],
        ));
  }
}
mofada commented 5 years ago

I am sorry, I made a mistake myself, I wrote AppBar.title to AppBar.leading.