2017-11-05 8 views
0

私は、Scaffold.of()関数と同様に、.of()メソッドを使ってアプリケーションのトップレベル状態を取得しようとしています。これは、(ストリップダウン)コードです:Flutter:子からトップレベルの状態を取得するとnullが返されます。

class IApp extends StatefulWidget {  
    @override 
    IAppState createState() => new IAppState(); 

    static IAppState of(BuildContext context) => 
    context.ancestorStateOfType(const TypeMatcher<IAppState>()); 
} 

アプリはrunApp(新しいIAPP)を使用して開始され

このウィジェットは、ホームページ作成:

@override 
    Widget build(BuildContext context) { 
    return new MaterialApp(
     // ommitted: some localization and theming details 
     home: new HomePage(), 
    ); 
    } 

はその後、私がアクセスしようとしますホームページからのステート(ステートフルウィジェット自体):

@override 
    Widget build(BuildContext context) { 
    return new Scaffold(
     // ommited: some Scaffold properties such as AppBar 
     // runtimeType not actual goal, but just for demonstration purposes 
     body: new Text(IApp.of(context).runtimeType.toString()), 
    ); 
    } 

これは奇妙なことですが、彼はIAppと同じファイルにホームページをコードしますが、余分なクラスとしてだけです。しかし、HomePage を別のファイル(相互にインポートするmain.dartとhomepage.dart)に配置すると、IApp.of(context)の戻り値はnullになります。

この原因は何ですか?それをどうやって修正することができますか?

+0

愚かな質問、それはirreleかもしれないファイルをインポートするときに、相対パス( "./homepage.dart")または絶対パス( "package:my_package/homepage.dart")を使用していますか? –

+0

私はパッケージのように絶対パスを使用しています:my_package/etc/file.dart –

+1

私は長い時間前に似たようなバグを抱えていましたが、相対パスを使って解決しましたか、それ以外のものでした^^ –

答えて

2

これは、ダーツがインポートをどのように解決するかによるものです。

単一のソースファイルがあるかもしれませんが、ビルド中に何らかの重複があります。

「myApp」で作業しているとします。ファイルをインポートするには、両方を行うことができます:

  • import 'relativePath/myFile.dart'
  • import 'package:myApp/path2/myFile.dart'

あなたは、彼らが同じファイル右を指していることを思うだろうか? しかし、いいえ。そのうちの1つが元のソースを指します。一方は、ビルドに使用される一時ファイルを指します。

両方のソリューションを混在させ始めると問題が発生します。コンパイラの場合、これらの2つのファイルはと異なるです。どちらがpackage:myApp/IAppから輸入​​は、あなたの場合はrelativePath/myApp/IApp

から輸入同じ​​と等しくないことを意味し、あなたのウィジェットツリーpakage:pathから​​に挿入されたが、あなたのIApp.of(context)使用IAppStateはローカルで解決します。 両方とも異なるランタイムタイプを持っています。したがってconst TypeMatcher<IAppState>()は一致しません。関数はnullを返します。

常に相対パスを使用してインポートします。 package:MyAppシンタックスは、同じリポジトリのテストプロジェクトで作業するときに便利です。パッケージ実装そのものではありません。


この動作をテストするための非常に簡単な方法があります。 あなたmain.dart次のインポートを追加でのみ

class Test { 
} 

を含むtest.dartファイルを作成します。

import 'package:myApp/test.dart' as Absolute; 
import './test.dart' as Relative; 

あなたが最終的に行うことで、これをテストすることができます。

new Relative.Test().runtimeType == new Absolute.Test().runtimeType 

スポイラー:結果はを偽

関連する問題