2017-10-31 35 views
1

私はFlutter &ダーツをここ数日間試しています。 私はこの日に1日以上立ち往生していますので、私はここにいます。アウターウィジェットからインナーウィジェットのアニメーションコントローラー(または状態)にアクセスするにはどうすればよいですか?

私はAlarmScreenを持っており、その中に2つのオブジェクトがあります。 1つはDraggableMoonWidgetで、もう1つはRisingSunWidgetです。

現在、RisingSunWidgetは画面の下からアニメーションされ、DraggableMoonWidgetはタッチでドラッグ可能です。私が達成したい何

は、RisingSunWidgetのアニメーションが停止し、DraggableMoonWidgetがドラッグされているときに変化するだろうというときということです。だから、私はMoonDragListenerを準備していますが、それでもわかりません。 (現在はリスナーをAlarmScreenに呼び出していますが、それは何ですか?)

私はこれを行う方法を一挙に試みました。

TLDR は、ユーザーがDraggableMoonWidgetに触れたとき、私はRisingSunWidgetのアニメーションコントローラを制御するにはどうすればよい、例えば、私はコントローラを停止し、別のポイントにそれをアニメーション化します。

ダーツ/フラッターの最善のアプローチは何ですか?

AlarmScreen

import 'package:flutter/widgets.dart'; 
import 'package:moonworshiper_app/backgrounds.dart'; 
import 'package:moonworshiper_app/ui/alarm/moon_draggable.dart'; 
import 'package:moonworshiper_app/ui/alarm/rising_sun.dart'; 

class AlarmScreen extends StatefulWidget { 
    @override 
    State<StatefulWidget> createState() { 
    return new _AlarmScreenState(); 
    } 
} 

class _AlarmScreenState extends State<AlarmScreen> { 
    bool _moonWasTouched = false; 

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

    @override 
    Widget build(BuildContext context) { 
    return new Stack(
     children: <Widget>[ 
     new DraggableMoonWidget(new MoonDragListener(this)), 
     new LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) { 
      return new RisingSunWidget(constraints.heightConstraints().maxHeight, _moonWasTouched); 
     }) 
     ], 
    ); 
    } 

    void _refreshSun() { 
    setState(() { 
     _moonWasTouched = true; 
    }); 
    } 
} 

class MoonDragListener { 
    _AlarmScreenState state; 

    MoonDragListener(this.state); 

    void onMoonDragStarted() { 
    state._refreshSun(); 
    } 
} 

DraggableMoonWidget

import 'package:flutter/widgets.dart'; 
import 'package:moonworshiper_app/ui/alarm/alarm_screen.dart'; 

class DraggableMoonWidget extends StatefulWidget { 

    final MoonDragListener moonStartListener; 

    DraggableMoonWidget(this.moonStartListener); 

    State<StatefulWidget> createState() => new _DraggableMoonState(); 
} 

class _DraggableMoonState extends State<DraggableMoonWidget> 
    with TickerProviderStateMixin { 


    final moonDragTween = new Tween<Offset>(
    begin: new Offset(0.0, -0.5), 
    end: new Offset(0.0, 0.5), 
); 

    var moonAnimListener; 
    AnimationController _animationController; 
    Animation<Offset> _dragAnimation; 
    AnimationController _dragAnimationController; 
    bool isFirstDraw = true; 

    @override 
    initState() { 
    super.initState(); 
    _animationController = new AnimationController(
     vsync: this, 
     duration: const Duration(milliseconds: 3000), 
    ); 
    _dragAnimationController = new AnimationController(vsync: this); 

    moonAnimListener = (AnimationStatus status) { 
     if (status == AnimationStatus.dismissed) { 
     _animationController.forward(); 
     } else if (status == AnimationStatus.completed) { 
     _animationController.reverse(); 
     } else if (status == AnimationStatus.forward) {} 
    }; 

    _dragAnimation = moonDragTween.animate(new CurvedAnimation(
     parent: _dragAnimationController, 
     curve: Curves.easeInOut, 
     reverseCurve: Curves.easeInOut)); 

    _dragAnimationController.animateTo(0.5, duration: new Duration()); 


    _animationController.addStatusListener(moonAnimListener); 


    _animationController.forward(); 
    } 

    @override 
    Widget build(BuildContext context) { 
    return new Container(
     child: new Center(
     child: new SlideTransition(
      position: _dragAnimation, 
      child: new GestureDetector(
      child: new Image.asset(
       "assets/moon.png", 
       width: 280.0, 
       height: 280.0, 
      ), 
      onVerticalDragStart: (DragStartDetails details) { 
       print("start:" + details.globalPosition.toString()); 
       _animationController.removeStatusListener(moonAnimListener); 
       _animationController.stop(); 
       _dragStartDetails = details; 

       _dragAnimationController.animateTo(0.5, 
        duration: new Duration(milliseconds: 50)); 

       if (isFirstDraw) { 
       isFirstDraw = false; 
       widget.moonStartListener.onMoonDragStarted(); 
       } 
      }, 
     ), 
     ), 
    ), 
//  margin: new EdgeInsets.only(top: 48.0), 
    ); 
    } 

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

RisingSunWidget

import 'package:flutter/widgets.dart'; 

class RisingSunWidget extends StatefulWidget { 
    // needed to calculate the offset map 
    final double screenHeight; 

    // that's how we know if the use touched the moon 
    final bool moonWasTouched; 

    RisingSunWidget(this.screenHeight, this.moonWasTouched); 

    @override 
    State<StatefulWidget> createState() { 
    return new RisingSunState(); 
    } 
} 

class RisingSunState extends State<RisingSunWidget> with TickerProviderStateMixin { 
    AnimationController _animationController; 
    Animation<Offset> _sunAnimation; 

    final double sunSize = 320.0; 

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

    _animationController = new AnimationController(
     vsync: this, 
     duration: const Duration(milliseconds: 6000), 
    ); 

    // how many suns fit in the height of our screen 

    assert(widget.screenHeight > sunSize); 

    double sunsInHeight = widget.screenHeight/sunSize; 

    print(sunsInHeight.toString() + " suns could fit on the user's screen"); 

    var sunsPlusMargins = sunsInHeight + 1; // required margins 

    final moonTween = new Tween<Offset>(
     begin: new Offset(0.0, -0.5 * sunsPlusMargins), 
     end: new Offset(0.0, 0.5 * sunsPlusMargins), //move by 8% of height max 
    ); 

    _sunAnimation = moonTween.animate(new CurvedAnimation(
     parent: _animationController, 
     curve: Curves.easeInOut, 
     reverseCurve: Curves.easeInOut, 
    )); 


    if (widget.moonWasTouched) { 
     _animationController.stop(); 
     _animationController.animateTo(0.68, 
      duration: new Duration(milliseconds: 2000)); 
    } else { 
     _animationController.animateTo(0.88, 
      duration: new Duration(milliseconds: 0)); 
     _animationController.animateTo(0.75, 
      duration: new Duration(milliseconds: 15000)); 
    } 
    } 

    @override 
    Widget build(BuildContext context) { 
    return new Center(
     child: new SlideTransition(
     position: _sunAnimation, 
     child: new Image.asset(
      "assets/sun.png", 
      width: sunSize, 
      height: sunSize, 
     ), 
    ), 
    ); 
    } 

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


} 

答えて

0

2の可能性:

  • はビルド方法が提供されるBuildContext contextを使用してください。 BuildContextには、特定の型の最も近い親を取得するメソッドがいくつかあります。
  • key属性を目的のウィジェットに渡します。 GlobalKeyとなります。 GlobalKeyを使用すると、Widgetまたはその状態に直接アクセスできます。
+0

私に例を教えてください。私はこれについてどこかで読んだことがありますが、サンプルコードを見つけることができませんでした。 – sofakingforever

関連する問題