簡體   English   中英

如何讓資產超過 AppBar?

[英]How to make asset exceeds the AppBar?

我想在 Flutter 中制作這個屏幕:

在此處輸入圖像描述

是否有可能做到這一點? 我的意思是讓蜥蜴圖退出AppBar並突出在主屏幕上?

這是資產:

在此處輸入圖像描述

是的,您必須制作自己的自定義應用程序欄

只需做一件事,將所有內容放入 Stack

Stack(
children:[
Position(
top:0,
left:0
child:YourLizardWidget()

),
Position(
top:0,
left:0
right:0
child:YourAppBar()

),
])

可能會奏效

您可以執行以下操作:

class NextPage extends StatefulWidget {

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

class _NextPageState extends State<NextPage> {

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        extendBodyBehindAppBar: true,
        backgroundColor: Colors.white,
        appBar: PreferredSize(
          preferredSize: Size(MediaQuery.of(context).size.width,200),
          child: Container(
            child: Stack(
              alignment: Alignment.topLeft,
              children: <Widget>[
                Container(color: Colors.red,width: MediaQuery.of(context).size.width,height: 100,),
                Container(width: 100,height: 200,color: Colors.blue,),
              ],
            ),
          ),
        ),
        body: Container(color: Colors.amber,),
      ),
    );
  }
}
  1. 我添加了一個 PreferredSize 小部件。 它就像一個定義應用欄最大寬度和高度的容器。

  2. 我添加了extendBodyBehindAppBar: true屬性,以便正文部分將從屏幕頂部開始,而不是從應用欄下方開始。

  3. 然后我只是將我的自定義應用欄添加為子屬性。

這是上面代碼的結果。 (紅色容器將是您的自定義應用欄,藍色容器可以替換為您的資產)

在此處輸入圖像描述

另一個使用應用程序Scaffold drawer的解決方案。

注意:如果你已經使用了drawer ,你也可以使用endDrawer代替。

在此處輸入圖像描述

此解決方案通過左側 animation 的幻燈片添加了一個不錯的小觸感。 (從右側滑動到末端抽屜)

關於解決方案的幾點:

  • AppBar ,我指定了leading: new Container()來隱藏漢堡菜單並為蜥蜴留出一些空間。
  • MyLizardMessage中,我使用了帶有verticalDirection: VerticalDirection.upColumn以便我的圖像(使用OverflowBox顯示在圓角Container的頂部)

完整的源代碼

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      home: HomePage(),
    ),
  );
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: new Container(),
        title: Text('Mes larfeuils'),
      ),
      drawer: MyLizardMessage(),
      body: MyContent(),
    );
  }
}

class MyLizardMessage extends StatelessWidget {
  const MyLizardMessage({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      verticalDirection: VerticalDirection.up,
      crossAxisAlignment: CrossAxisAlignment.start,
      mainAxisAlignment: MainAxisAlignment.end,
      children: [
        Padding(
          padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 0.0),
          child: Container(
            padding: EdgeInsets.all(8.0),
            decoration: BoxDecoration(
              color: Colors.white,
              border: Border.all(
                color: Colors.black87,
              ),
              borderRadius: BorderRadius.all(
                Radius.circular(20),
              ),
            ),
            child: Text(
                'Cupim beef ribs t-bone, shank short loin chicken pork belly prosciutto ribeye hamburger doner pork chop leberkas. '),
          ),
        ),
        IntrinsicWidth(
          child: Container(
            height: 82.0,
            child: OverflowBox(
              maxHeight: 85.0,
              child: Image.asset(
                'images/lizard.png',
                height: 85.0,
              ),
            ),
          ),
        ),
      ],
    );
  }
}

class MyContent extends StatelessWidget {
  const MyContent({
    Key key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Column(
        children: [
          Text(
            'Bacon ipsum dolor amet corned beef pork pork loin, chislic tri-tip picanha beef leberkas short ribs sirloin salami buffalo drumstick. Shankle chislic sirloin pork t-bone short ribs swine sausage hamburger chicken tail. Ham hock doner pancetta, jowl hamburger bacon prosciutto. Strip steak picanha jerky chislic. Strip steak prosciutto beef, pastrami corned beef t-bone frankfurter bacon rump sausage swine filet mignon fatback pork loin. Swine shank short ribs ham porchetta.',
          ),
          const SizedBox(height: 16.0),
          ElevatedButton(
              onPressed: () => Scaffold.of(context).openDrawer(),
              child: Text('Open message dialog')),
          const SizedBox(height: 16.0),
          Text(
            'T-bone venison picanha, corned beef meatloaf bacon buffalo sirloin biltong pancetta strip steak. Ham hock meatloaf tongue pastrami t-bone. Flank prosciutto shoulder chicken, turducken biltong hamburger short ribs beef buffalo brisket chislic filet mignon. Short ribs pork chop jowl jerky, beef ribs sirloin beef kevin landjaeger boudin chislic shankle. Tail pastrami swine drumstick, landjaeger turkey pig ground round.',
          ),
        ],
      ),
    );
  }
}

這是另一個使用OverlayEntry的解決方案。

在此處輸入圖像描述

這一次,您可以在消息出現時定義一個 animation。 但是消息是非模態的。 您仍然可以使用消息下方的應用程序 UI。 在上面的截屏視頻中,我通過單擊ElevatedButton打開消息,然后使用相同的按鈕和消息中的關閉圖標將其關閉。 我還展示了AppBar操作按鈕在顯示消息時也是可點擊的。

完整的源代碼

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      home: HomePage(),
    ),
  );
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: new Container(),
        title: Text('Mes larfeuils'),
        actions: [IconButton(icon: Icon(Icons.add), onPressed: () {})],
      ),
      body: MyContent(),
    );
  }
}

class MyLizardMessage extends StatefulWidget {
  final VoidCallback onClose;

  const MyLizardMessage({
    Key key,
    this.onClose,
  }) : super(key: key);

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

class _MyLizardMessageState extends State<MyLizardMessage>
    with SingleTickerProviderStateMixin {
  AnimationController controller;
  Animation<Offset> position;

  @override
  void initState() {
    super.initState();

    controller =
        AnimationController(vsync: this, duration: Duration(milliseconds: 300));
    position = Tween<Offset>(begin: Offset(-1.0, 0.0), end: Offset.zero)
        .animate(CurvedAnimation(parent: controller, curve: Curves.easeInOut));

    controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return SlideTransition(
      position: position,
      child: Column(
        verticalDirection: VerticalDirection.up,
        crossAxisAlignment: CrossAxisAlignment.start,
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          Material(
            child: Padding(
              padding:
                  const EdgeInsets.symmetric(horizontal: 8.0, vertical: 0.0),
              child: Container(
                padding: EdgeInsets.all(8.0),
                decoration: BoxDecoration(
                  color: Colors.white,
                  border: Border.all(
                    color: Colors.black87,
                  ),
                  borderRadius: BorderRadius.all(
                    Radius.circular(20),
                  ),
                ),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Expanded(
                      child: Text(
                        'Cupim beef ribs t-bone, shank short loin chicken pork belly prosciutto ribeye hamburger doner pork chop leberkas. ',
                        style: TextStyle(inherit: false),
                      ),
                    ),
                    GestureDetector(
                      onTap: () => widget.onClose?.call(),
                      child: Icon(Icons.close),
                    ),
                  ],
                ),
              ),
            ),
          ),
          IntrinsicWidth(
            child: Container(
              height: 82.0,
              child: OverflowBox(
                maxHeight: 85.0,
                child: Image.asset(
                  'images/lizard.png',
                  height: 85.0,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class MyContent extends StatefulWidget {
  const MyContent({
    Key key,
  }) : super(key: key);

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

class _MyContentState extends State<MyContent> {
  OverlayEntry _overlayEntry;
  bool get _isMessageShown => _overlayEntry != null && _overlayEntry.mounted;

  OverlayEntry _createOverlayEntry() {
    return OverlayEntry(
      builder: (context) {
        final width = MediaQuery.of(context).size.width;
        return Positioned(
          top: 0,
          left: 0,
          width: width,
          child: MyLizardMessage(onClose: () => _hideMessage()),
        );
      },
      opaque: false,
    );
  }

  _showMessage() {
    _overlayEntry = _createOverlayEntry();
    Overlay.of(context).insert(_overlayEntry);
    setState(() {});
  }

  _hideMessage() {
    _overlayEntry?.remove();
    _overlayEntry = null;
    setState(() {});
  }

  _toggleMessage() => _isMessageShown ? _hideMessage() : _showMessage();

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Column(
        children: [
          Text(
            'Bacon ipsum dolor amet corned beef pork pork loin, chislic tri-tip picanha beef leberkas short ribs sirloin salami buffalo drumstick. Shankle chislic sirloin pork t-bone short ribs swine sausage hamburger chicken tail. Ham hock doner pancetta, jowl hamburger bacon prosciutto. Strip steak picanha jerky chislic. Strip steak prosciutto beef, pastrami corned beef t-bone frankfurter bacon rump sausage swine filet mignon fatback pork loin. Swine shank short ribs ham porchetta.',
          ),
          const SizedBox(height: 16.0),
          ElevatedButton(
              onPressed: () => _toggleMessage(),
              child: Text(_isMessageShown
                  ? 'Close message dialog'
                  : 'Open message dialog')),
          const SizedBox(height: 16.0),
          Text(
            'T-bone venison picanha, corned beef meatloaf bacon buffalo sirloin biltong pancetta strip steak. Ham hock meatloaf tongue pastrami t-bone. Flank prosciutto shoulder chicken, turducken biltong hamburger short ribs beef buffalo brisket chislic filet mignon. Short ribs pork chop jowl jerky, beef ribs sirloin beef kevin landjaeger boudin chislic shankle. Tail pastrami swine drumstick, landjaeger turkey pig ground round.',
          ),
        ],
      ),
    );
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM