Flutter 动画可见性与不透明度

问题描述 投票:0回答:4

Flutter 可见性小部件允许隐藏和禁用其中包含的所有内容。但是,我想要为不透明度设置动画并调用可见性。使用可见性小部件会覆盖动画不透明度。根据我对其他语言的了解,这是可以预料的。

有没有一种简单方便的方法来实现动画的不透明度和可见性。它会让生活比设置计时器更简单。

下面的示例使用 bool of hasAccess 使用 Provider 作为状态管理。

child: Stack(
  children: [

  Visibility(
    visible: hasAccess ? false : true,
    child: AnimatedOpacity(
      duration: Duration(milliseconds: 400),
      opacity: hasAccess ? 0 : 1,
      child: Text('Not logged in'),
  )), 

  Visibility(
    visible: hasAccess ? true : false,
    child: AnimatedOpacity(
      duration: Duration(milliseconds: 400),
      opacity: hasAccess ? 1 : 0,
      child: Text('Is logged in'),
   ),
  ), 
 ],
)
flutter animation visibility opacity
4个回答
14
投票

我希望这能解决问题。您需要在可见性小部件中设置

maintainAnimation=true
maintainState=true

Visibility(
     visible: hasAccess,
     maintainAnimation: true,
     maintainState: true,
     child: AnimatedOpacity(
        duration: const Duration(milliseconds: 500),
        curve: Curves.fastOutSlowIn,
        opacity: hasAccess ? 1 : 0,
        child: Text('abc')
     )
    )

3
投票

Visibility
Opacity
是完全不同的两个东西。

Opacity
可用于更改其子级的不透明度。
AnimatedOpacity
允许此动画,而
FadeTransition
允许此过渡。然而,不透明度仅处理不透明度。即使你看不到,孩子仍然画在屏幕上。它仍然会响应指针事件并且仍然占用计算资源。

Visibility
类是包括
IgnorePointer
在内的各种其他类的合并。根据给定的设置,它要么用占用最少资源且没有内容的小部件完全替换子部件(默认为
SizedBox.shrink()
),要么移动它
OffScreen
,或者只是阻止指针事件。它总是会在没有任何动画的情况下使其不可见。它可以有效地完全替换小部件,将其移出屏幕或禁用指针事件,同时始终使子部件不可见。

使用

AnimatedOpacity
FadeTransition
将允许您设置不透明度的动画。一旦动画完成并且子项的不透明度为 0,就可以使用
Visibility
。您可以通过侦听器、计时器或您能想到的任何其他方法找到动画的状态。

你会发现像AnimatedOpacity这样的Widget也有回调函数。当动画完成时,您可以使用这些函数之一。您可以创建一个名为

_visible
的状态,例如
bool
。然后在
false
的动画完成后将其设置为
AnimatedOpacity
。然后,您可以将 AnimatedOpacity 的子级包装在 Visibility Widget 中,将其属性设置为您的
_visible
状态布尔值。

Visibility(visibility: _visible, child: <yourChildWidget>);

0
投票

如果您想要简单的解决方案,请使用这个:

AnimatedOpacity(
  // If the widget is visible, animate to 0.0 (invisible).
  // If the widget is hidden, animate to 1.0 (fully visible).
  opacity: _visible ? 1.0 : 0.0,
  duration: const Duration(milliseconds: 500),
  // The green box must be a child of the AnimatedOpacity widget.
  child: Container(
    width: 200.0,
    height: 200.0,
    color: Colors.green,
  ),
)

原始链接:https://docs.flutter.dev/cookbook/animation/opacity-animation


0
投票
import 'package:flutter/material.dart';

class AnimatedVisibility extends StatelessWidget {
  bool isNotBuild = true;

  final bool visible;
  final Widget child;
  final Curve curve;
  final Duration duration;
  final alwaysIncludeSemantics;

  AnimatedVisibility({
    super.key,
    this.visible = true,
    required this.child,
    this.curve = Curves.linear,
    required this.duration,
    this.alwaysIncludeSemantics = false
  });

  @override
  Widget build(BuildContext context) {
    isNotBuild = false;

    return AnimatedOpacity(
      opacity: visible ? 1 : 0,
      duration: duration,
      curve: curve,
      alwaysIncludeSemantics: alwaysIncludeSemantics,
      child: FutureBuilder(
        future: Future.delayed(isNotBuild ? Duration.zero : duration),
        builder: (_, snapshot) => Visibility(child: child, visible: snapshot.connectionState != ConnectionState.done || visible),
      ),
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.