2017-08-03 50 views
0

我得到了很大的幫助來構建這個動態的expansionTile,現在我試圖添加一個傳遞給onTap的類,以便它可以傳遞到另一個頁面。我嘗試了幾件事,並不斷收到此錯誤。如果我不向onTap添加任何內容,那麼函數會調用所有作品,但沒有數據可以傳遞。Flutter將類添加到由未來的構建器構建的小部件

任何指導都會很棒。

我得到這個錯誤:

I/flutter (15773): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════ 
I/flutter (15773): The following assertion was thrown building FutureBuilder(dirty; state: 
I/flutter (15773): _FutureBuilderState#fe2cf()): 
I/flutter (15773): setState() or markNeedsBuild() called during build. 
I/flutter (15773): This Overlay widget cannot be marked as needing to build because the framework is already in the 
I/flutter (15773): process of building widgets. A widget can be marked as needing to be built during the build phase 
I/flutter (15773): only if one of its ancestors is currently building. This exception is allowed because the framework 
I/flutter (15773): builds parent widgets before children, which means a dirty descendant will always be built. 
I/flutter (15773): Otherwise, the framework might not visit this widget during this build phase. 
I/flutter (15773): The widget on which setState() or markNeedsBuild() was called was: 
I/flutter (15773): Overlay([LabeledGlobalKey<OverlayState>#5da5e]; state: OverlayState#12b2d(tracking 2 tickers; 
I/flutter (15773): entries: [OverlayEntry#b3821(opaque: true; maintainState: false), OverlayEntry#b2a00(opaque: 
I/flutter (15773): false; maintainState: true), OverlayEntry#a0c04(opaque: true; maintainState: false), 
I/flutter (15773): OverlayEntry#11271(opaque: false; maintainState: true), OverlayEntry#54209(opaque: false; 
I/flutter (15773): maintainState: false), OverlayEntry#1a91b(opaque: false; maintainState: true)])) 
I/flutter (15773): The widget which was currently being built when the offending call was made was: 
I/flutter (15773): FutureBuilder(dirty; state: _FutureBuilderState#fe2cf()) 
I/flutter (15773): 

我想現在運行該代碼的環比JSON在ExpansionTile小工具下,我的元素添加到_onTap功能,並且還試圖只是建立該類並將類添加到_onTap並且錯誤仍在繼續。沒有它,它工作正常,但我需要在另一頁上的數據。任何想法都會很棒,我相信我錯過了一些愚蠢的事情,因爲我是新來的其他語言。

import 'dart:async'; 

import 'package:flutter/material.dart'; 
import 'package:flutter/services.dart'; 
import 'package:shared_preferences/shared_preferences.dart'; 
import 'package:http/http.dart' as http; 
import 'package:cswauthapp/models.dart'; 
import 'package:cswauthapp/FacPage.dart'; 
import 'package:cswauthapp/ReasonPage.dart'; 

import 'dart:convert'; 


class SpecPage extends StatefulWidget { 
    SpecPage({Key key, this.spec}) : super(key: key); 

    final Specialties spec; 

    //final Facilities fac; 
    //static const String routeName = "/specs/spec"; 

    @override 
    _SpecPageState createState() => new _SpecPageState(); 
} 

class _SpecPageState extends State<SpecPage> { 
    Future<http.Response> _responseFuture; 

    bool _authenticated = false; 
    bool _dataReceived = false; 
    SharedPreferences prefs; 
    List myReasonlist; 
    int listcount = 0; 
    int specid; 

    @override 
    void initState() { 
    super.initState(); 
    _responseFuture = http.get('http://174.138.61.246:8080/support/dc/${widget.spec.id}'); 

    _getPrefs(); 
    //_getSpecialty(); 
    //_getFacilities(); 
    } 

    _getPrefs() async { 
    prefs = await SharedPreferences.getInstance(); 
    _authenticated = prefs.getBool('authenticated'); 
    print('AUTH3: ' + _authenticated.toString()); 
    print('AUTHCODE3: ' + prefs.getString('authcode')); 
    prefs.setInt('specid', widget.spec.id); 
    print('SPECID: ' + prefs.getInt('specid').toString()); 
    specid = await prefs.getInt('specid'); 
    _getReasons(); 
    } 

    var jsonCodec = const JsonCodec(); 

    _getReasons() async { 
    var _url = 'http://csw.abbadabba.tech:8080/support/getreferralreasons/$specid'; 

    var http = createHttpClient(); 
    var response = await http.get(_url); 

    var reasons = await jsonCodec.decode(response.body); 

    myReasonlist = await reasons.toList(); 
    //_dataReceived = true; 

    if (mounted) { 
     setState(() { 
     _dataReceived = true; 
     listcount = myReasonlist.length; 
     }); 
    } 
    } 

    Future<Null> _onRefresh() { 
    Completer<Null> completer = new Completer<Null>(); 
    Timer timer = new Timer(new Duration(seconds: 3),() { 
     completer.complete(); 
    }); 
    return completer.future; 
    } 


    @override 
    Widget build(BuildContext context) { 
    var _children = <Widget>[ 

     new Center(
     child: new Container(
      padding: new EdgeInsets.only(
       left: 10.0, right: 10.0, top: 20.0, bottom: 10.0), 
      child: new Text('Referral Reasons for '+widget.spec.name, 
      style: new TextStyle(fontSize: 30.0), 
      textAlign: TextAlign.center, 
     ), 
     ), 
    ), 

     new Expanded(
      child: new FutureBuilder(
      future: _responseFuture, 
      builder: (BuildContext context, AsyncSnapshot<http.Response> response) { 
       if (!response.hasData) { 
       return const Center(
        child: const Text('Loading...'), 
       ); 
       } else if (response.data.statusCode != 200) { 
       return const Center(
        child: const Text('Error loading data'), 
       ); 
       } else { 
       List<dynamic> json = JSON.decode(response.data.body); 
       return new MyExpansionTileList(json); 
       } 
      }, 
     ), 

    ), 

     /*new Expanded(
     flex: 1, 
     child: new RefreshIndicator(
      child: new ListView.builder(
      itemBuilder: _itemBuilder, 
      itemCount: listcount, 
     ), 
      onRefresh: _onRefresh, 

     ), 
    ),*/ 

    ]; 
    return new Scaffold(
     appBar: new AppBar(title: new Text("My Specialty")), 
     body: new Column(
     children: _children, 
    ), 
    ); 
    } 

    /*Widget _itemBuilder(BuildContext context, int index) { 
    Reasons reason = getReason(index); 
    return new ReasonWidget(reason: reason,); 
    }*/ 

    Reasons getReason(int index) { 
    return new Reasons(
     myReasonlist[index]['rid'], 
     myReasonlist[index]['reason'], 
     myReasonlist[index]['sid'], 
     myReasonlist[index]['specname'] 
    ); 
    //return new Specialties.fromMap(mylist[index]); 

    } 
} 

class MyExpansionTileList extends StatelessWidget { 
    final List<dynamic> elementList; 

    MyExpansionTileList(this.elementList); 

    List<Widget> _getChildren() { 
    List<Widget> children = []; 
    elementList.forEach((element) { 
     children.add(
     new MyExpansionTile(element['did'], element['dname']), 
    ); 
    }); 
    return children; 
    } 

    @override 
    Widget build(BuildContext context) { 
    return new ListView(
     children: _getChildren(), 
    ); 
    } 
} 

class MyExpansionTile extends StatefulWidget { 
    final int did; 
    final String name; 

    MyExpansionTile(this.did, this.name); 
    @override 
    State createState() => new MyExpansionTileState(); 
} 

class MyExpansionTileState extends State<MyExpansionTile> { 
    PageStorageKey _key; 
    Future<http.Response> _responseFuture; 
    List<Widget> reasonList; 
    List reasList; 
    //Reasons reason; 

    @override 
    void initState() { 
    super.initState(); 
    _responseFuture = 
     http.get('http://174.138.61.246:8080/support/dcreasons/${widget.did}'); 
    } 

    @override 
    Widget build(BuildContext context) { 
    _key = new PageStorageKey('${widget.did}'); 
    return new ExpansionTile(
     key: _key, 
     title: new Text(widget.name, 
     style: new TextStyle(fontWeight: FontWeight.bold), 
    ), 
     children: <Widget>[ 
     new FutureBuilder(
      future: _responseFuture, 
      builder: 
       (BuildContext context, AsyncSnapshot<http.Response> response) { 
      if (!response.hasData) { 
       return const Center(
       child: const Text('Loading...'), 
      ); 
      } else if (response.data.statusCode != 200) { 
       return const Center(
       child: const Text('Error loading data'), 
      ); 
      } else { 
       List<dynamic> json = JSON.decode(response.data.body); 
       reasonList = []; 
       json.forEach((element) { 

       reasonList.add(new ListTile(
        dense: true, 
        title: new Text(element['reason']), 
        onTap: _onTap(new Reasons(element['rid'], element['reason'], element['sid'], element['specname'])), 
       )); 
       }); 
       //reasList = json.toList(); 
       return new Column(children: reasonList); 
      } 

      }, 

     ) 
     ], 
    ); 
    } 

    _onTap(Reasons reason) { 
    Route route = new MaterialPageRoute(
     settings: new RouteSettings(name: "/reasons/reason"), 
     builder: (BuildContext context) => new ReasonPage(reason: reason), 
    ); 
    Navigator.of(context).push(route); 
    } 
} 

回答

1

我想通了,不知道爲什麼,但我做了內聯方法,它的工作。

@override 
    Widget build(BuildContext context) { 
    _key = new PageStorageKey('${widget.did}'); 
    return new ExpansionTile(
     key: _key, 
     title: new Text(widget.name, 
     style: new TextStyle(fontWeight: FontWeight.bold), 
    ), 
     children: <Widget>[ 
     new FutureBuilder(
      future: _responseFuture, 
      builder: 
       (BuildContext context, AsyncSnapshot<http.Response> response) { 
      if (!response.hasData) { 
       return const Center(
       child: const Text('Loading...'), 
      ); 
      } else if (response.data.statusCode != 200) { 
       return const Center(
       child: const Text('Error loading data'), 
      ); 
      } else { 
       List<dynamic> json = JSON.decode(response.data.body); 
       reasonList = []; 
       json.forEach((element) { 

       reasonList.add(new ListTile(
        dense: true, 
        leading: new Text(' - '), 
        title: new Text(element['reason']), 
        //HERE IS WHERE I FIXED IT. 
        onTap:() { 
        Route route = new MaterialPageRoute(
         settings: new RouteSettings(name: "/reasons/reason"), 
         builder: (BuildContext context) => new ReasonPage(id: element['rid'], reason: element['reason'], sid: element['sid']), 
        ); 
        Navigator.of(context).push(route); 
        }, 
       )); 
       }); 
       //reasList = json.toList(); 
       return new Column(children: reasonList); 
      } 

      }, 

     ) 
     ], 
    ); 
    } 
相關問題