我们如何将AnimatedPositioned小部件动画到屏幕右侧,并在按钮按下时隐藏它?

huangapple go评论62阅读模式
英文:

How can we animate an AnimatedPositioned widget to right of screen and hide it on button press?

问题

我在尝试正确定位我的侧边栏小部件时遇到了很多问题。

我尝试了许多不同的位置属性更改,但还没有能够将侧边栏放在屏幕的右侧。此外,我不断收到有关未设置约束以及未设置大小的错误。这让我感到困惑,因为容器子元素确实具有大小,而动画小部件正在提供约束...所以我不确定该如何解决这个问题。

如果我注释掉AnimatedPositioned小部件的所有约束,那么侧边栏确实会出现在左侧。任何尝试添加位置都会导致错误。

这里的目标是使蓝色侧边栏出现在屏幕的右侧,当按下按钮时,它会从屏幕右侧消失,然后页面内容会填充整个屏幕宽度。

英文:

I am having a lot of trouble getting a layer of my sidebar widget positioned properly on the right of the screen.

I've tried many different position property changes and haven't been able to get the sidebar on the right side yet. Furthermore, I keep getting errors for constraints not set as well as size not set. This is confusing since the container child does have size and the animated widget is giving a constraint... so I'm not sure how to go about this.

If I comment out all constraints of the AnimatedPositioned widget, then the sidebar does appear on the left. Any attempt to add a position results in an error.

The goal here is the blue sidebar on the right of the screen & when a button is pressed it disappears right off-screen and the page content then fills the entire screen width.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Scaffold(
        body: SafeArea(
          child: Center(
            child: MyWidget(),
          ),
        ),
      ),
    );
  }
}

class MyWidget extends StatefulWidget {
  const MyWidget({Key? key}) : super(key: key);

  @override
  State<MyWidget> createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> {
  bool showSidebar = true;

  @override
  Widget build(BuildContext context) {
    double width = MediaQuery.of(context).size.width;

    return SafeArea(
      child: Stack(
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.end,
            mainAxisSize: MainAxisSize.max,
            children: [
              Expanded(
                child: SingleChildScrollView(
                  child: Column(
                    children: [
                      Container(
                        width: double.maxFinite,
                        height: 700,
                        color: Colors.red,
                      ),
                      Container(
                        width: double.maxFinite,
                        height: 700,
                        color: Colors.yellow,
                      ),
                    ],
                  ),
                ),
              ),
              // Invisible box to allow space for sidebar when shown or hidden
              (showSidebar) ? SizedBox(width: 43) : SizedBox(width: 0),
            ],
          ),
          // Sidebar box
          AnimatedPositioned(
            // left: 0, // (showSidebar) ? width - 43 : width,
            // width: 43,
            // top: 0,
            curve: Curves.ease,
            duration: const Duration(milliseconds: 500),
            child: Container(
              width: 43.0,
              color: Colors.blue,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.start,
                children: const [
                  SizedBox(height: 120.0),
                  Expanded(
                    child: Center(
                      child: RotatedBox(
                        quarterTurns: -1,
                        child: Text(
                          'EXAMPLE MENU BAR - PAGE 1',
                          style: TextStyle(
                              fontSize: 20.0, fontWeight: FontWeight.bold, color: Colors.white),
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
          Padding(
            padding: const EdgeInsets.only(left: 5.0, top: 5.0, right: 4.0),
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                fakeButton(),
                Column(
                  children: [
                    fakeButton(),
                    fakeButton(),
                    fakeButton(),
                  ],
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  // Fake buttons
  Widget fakeButton() {
    return GestureDetector(
      onTap: () => {
        setState(() {
          (showSidebar) ? showSidebar = false : showSidebar = true;
        })
      },
      child: SizedBox(
        height: 35,
        width: 35,
        child: Stack(
          children: const [
            Icon(
              Icons.circle,
              color: Colors.green,
              size: 35.0,
            ),
            Align(
              alignment: Alignment.center,
              child: Text(
                'HIDE',
                style: TextStyle(
                  color: Colors.white,
                  fontWeight: FontWeight.bold,
                  fontSize: 9.0,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

答案1

得分: 1

你需要给属性 right:0 并且给子容器一个 高度值,这个高度值应该是屏幕大小。

尝试这样做:

AnimatedPositioned(
    // left: 0, // (showSidebar) ? width - 43 : width,
    // width: 43,
    // top: 0,
    right: 0,
    curve: Curves.ease,
    duration: const Duration(milliseconds: 500),
    child: Container(
        width: 43.0,
        height: MediaQuery.of(context).size.height,
        color: Colors.blue,
        child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: const [
                SizedBox(height: 120.0),
                Expanded(
                    child: Center(
                        child: RotatedBox(
                            quarterTurns: -1,
                            child: Text(
                                'EXAMPLE MENU BAR - PAGE 1',
                                style: TextStyle(
                                    fontSize: 20.0, fontWeight: FontWeight.bold, color: Colors.white),
                            ),
                        ),
                    ),
                ),
            ],
        ),
    ),
)
英文:

You have to give a property right:0 and give the child container a height value and it should be the screen size.

Try this:

AnimatedPositioned(
    // left: 0, // (showSidebar) ? width - 43 : width,
    // width: 43,
    // top: 0,
    right: 0,
    curve: Curves.ease,
    duration: const Duration(milliseconds: 500),
    child: Container(
      width: 43.0,
      height: MediaQuery.of(context).size.height,
      color: Colors.blue,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        children: const [
          SizedBox(height: 120.0),
          Expanded(
            child: Center(
              child: RotatedBox(
                quarterTurns: -1,
                child: Text(
                  'EXAMPLE MENU BAR - PAGE 1',
                  style: TextStyle(
                      fontSize: 20.0, fontWeight: FontWeight.bold, color: Colors.white),
                ),
              ),
            ),
          ),
        ],
      ),
    ),
  ),

huangapple
  • 本文由 发表于 2023年6月22日 02:16:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/76526100.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定