Dart 如何在flatter中收听抽屉打开/关闭动画

Dart 如何在flatter中收听抽屉打开/关闭动画,dart,flutter,flutter-animation,Dart,Flutter,Flutter Animation,作为一名新手,我正在通过重新创建现有的Android应用程序进行学习。然而,我很难制作一个“旋转、成长的主图标”,它应该与抽屉打开/关闭动画同步 所需的抽屉/主图标行为如下所示: 我在Android中通过实现 DrawerListener.onDrawerSlide(View drawerView, float slideOffset) 我在Flatter中这样做的天真方法是使用ScaleTransition和RotationTransition,听打开/关闭抽屉的相同动画 我可以看到Sc

作为一名新手,我正在通过重新创建现有的Android应用程序进行学习。然而,我很难制作一个“旋转、成长的主图标”,它应该与抽屉打开/关闭动画同步

所需的抽屉/主图标行为如下所示:

我在Android中通过实现

DrawerListener.onDrawerSlide(View drawerView, float slideOffset) 
我在Flatter中这样做的天真方法是使用ScaleTransition和RotationTransition,听打开/关闭抽屉的相同动画

我可以看到ScaffoldState有一个抽屉控制器状态,但它是私有的

final GlobalKey<DrawerControllerState> _drawerKey = new GlobalKey<DrawerControllerState>();
final GlobalKey\u drawerKey=new GlobalKey();
即使我能以某种方式访问抽屉控制器状态(我不知道如何访问),我也不能访问_animationChanged()和_controller,因为它们都是抽屉控制器状态的私有成员

我觉得我走错了方向,有一种更好的方法更自然,我看不见


有谁能描述一下实现这一点的方法吗?

您可以先参考其他人对stackoverflow的回复

我的解决方案:

获取抽屉Widget上的抽屉状态

initState() : open drawer
dispose() : close drawer
按抽屉服务提供程序显示抽屉状态

请参阅完整代码

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:provider/provider.dart';


void main() {
  runApp(
    MultiProvider(
      providers: [
        Provider(create: (_) => DrawerService()),
      ],
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  DrawerService _drawerService;
  String drawerStatus = 'close';
  @override
  void initState() {
    super.initState();
    _drawerService = Provider.of(context, listen: false);
    _listenDrawerService();
  }

  _listenDrawerService() {
    _drawerService.status.listen((status) {
      if(status) {
        drawerStatus = 'open';
      } else {
        drawerStatus = 'close';
      }
      setState(() { });
    });
  }

  @override
  Widget build(BuildContext context) {
    Color bgColor = Colors.yellow;
    if(drawerStatus == 'open') {
      bgColor = Colors.red;
    }

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      drawer: DrawerWidget(),
      body: Container(
        decoration: BoxDecoration(color: bgColor),
        height: 300,
        child: Center(child: Text(drawerStatus),),
      ),
    );
  }
}


class DrawerWidget extends StatefulWidget {
  @override
  _DrawerWidgetState createState() => _DrawerWidgetState();
}

class _DrawerWidgetState extends State<DrawerWidget> {  
  DrawerService _drawerService;

  @override
  void initState() {
    super.initState();
    _drawerService = Provider.of(context, listen: false);
    _drawerService.setIsOpenStatus(true);
  }

  @override
  Widget build(BuildContext context) {
    return Drawer(
      child: Center(child: Text('drawer'),),
    );
  }

  @override
  void dispose() {
    super.dispose();
    _drawerService.setIsOpenStatus(false);
  }
}

class DrawerService {
  StreamController<bool> _statusController = StreamController.broadcast();
  Stream<bool> get status => _statusController.stream;

  setIsOpenStatus(bool openStatus) {
    _statusController.add(openStatus);
  }
}
导入“包装:颤振/材料.省道”;
导入“dart:async”;
导入“包:provider/provider.dart”;
void main(){
runApp(
多供应商(
供应商:[
提供程序(创建:(\u)=>DrawerService()),
],
子项:MyApp(),
),
);
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“颤振演示”,
主题:主题数据(
主样本:颜色。蓝色,
视觉密度:视觉密度。自适应平台密度,
),
主页:MyHomePage(标题:“颤振演示主页”),
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>\u MyHomePageState();
}
类_MyHomePageState扩展状态{
付款人服务——付款人服务;
字符串抽屉状态='close';
@凌驾
void initState(){
super.initState();
_drawerService=Provider.of(上下文,侦听:false);
_listenDrawerService();
}
_listenDrawerService(){
_drawerService.status.listen((状态){
如果(状态){
付款人状态='打开';
}否则{
付款人状态='关闭';
}
setState((){});
});
}
@凌驾
小部件构建(构建上下文){
颜色bgColor=Colors.yellow;
如果(抽屉状态==“打开”){
bgColor=Colors.red;
}
返回脚手架(
appBar:appBar(
标题:文本(widget.title),
),
抽屉:抽屉Widget(),
主体:容器(
装饰:盒子装饰(颜色:bgColor),
身高:300,
子:中心(子:文本(抽屉状态),),
),
);
}
}
类DrawerWidget扩展StatefulWidget{
@凌驾
_抽屉WidgetState createState()=>\u抽屉WidgetState();
}
类DrawerWidgetState扩展了状态{
付款人服务——付款人服务;
@凌驾
void initState(){
super.initState();
_drawerService=Provider.of(上下文,侦听:false);
_付款人服务setIsOpenStatus(真);
}
@凌驾
小部件构建(构建上下文){
回程抽屉(
子对象:居中(子对象:文本('drawer'),),
);
}
@凌驾
无效处置(){
super.dispose();
_付款人服务setIsOpenStatus(假);
}
}
类抽屉服务{
StreamController _statusController=StreamController.broadcast();
Stream get status=>\u statusController.Stream;
setIsOpenStatus(布尔开放状态){
_statusController.add(openStatus);
}
}
希望能帮助一些人