2017-08-01 20 views
1

尋找動態構建擴充文件列表的指導。我有一個從json API動態構建的成功Listview,但是找不到構建expansionTile的任何示例。我有一個api調用,可以返回最高級別,而另一個調用則需要每個頂級用戶返回擴展列表。任何人都有這樣的例子嗎?我已經找到了這個靜態的例子,但不清楚如何使它變成動態的。撲動動態擴充文件夾

這是我想出的一些代碼。我可以看到瓷磚標題部分,並可以看到json進來的瓷磚身體,但無法弄清楚如何獲得在正文中的列表標題的正確名稱,沒有任何我嘗試設置它的作品。有任何想法嗎?

import 'dart:async'; 
import 'package:intl/intl.dart'; 

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:flutter/foundation.dart'; 
import 'dart:convert'; 

var jsonCodec = const JsonCodec(); 
List<Exp> myReasonList; 
List myDCList; 
int mycount = 0; 

void main() { 
    runApp(new MyApp()); 

} 



class MyApp extends StatelessWidget { 
    @override 
    Widget build(BuildContext context) { 
    return new MaterialApp(
     title: 'ExpansionTile Test', 
     home: new MyHomePage(), 
    ); 
    } 
} 

class MyHomePage extends StatefulWidget { 
    @override 
    _MyHomePageState createState() => new _MyHomePageState(); 
} 

class _MyHomePageState extends State<MyHomePage> { 

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

    _getData(); 
    //_getSpecialty(); 
    } 

    _getData() async { 
    var _url = 'http://174.138.61.246:8080/support/dc/1'; 

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

    var dc = await jsonCodec.decode(response.body); 
    myDCList = await dc.toList(); 



    print('DC: '+myDCList.toString()); 

    if (mounted) { 
     setState(() { 
     //_dataReceived = true; 
     mycount = myDCList.length; 
     }); 
    } 

    } 

    Future _getChildren(int did) async { 

    var _url2 = 'http://174.138.61.246:8080/support/dcreasons/$did'; 
    var http = createHttpClient(); 
    var response = await http.get(_url2); 
    var reasons = await jsonCodec.decode(response.body); 
    myReasonList = await reasons.toList(); 
    print('REASONS: '+ myReasonList.toString()); 


    return myReasonList; 
    } 

    @override 
    Widget build(BuildContext context) { 
    return new Scaffold(
     appBar: new AppBar(
     title: new Text('ExpansionTile Test'), 
    ), 
     body: new ListView.builder(
     itemBuilder: _itemBuilder, 
     itemCount: mycount, 
    ), 
    ); 
    } 

    Widget _itemBuilder(BuildContext context, int index) { 
    Exp exp = getExp(index); 
    return new ListChild(exp: exp,); 
    } 

    Exp getExp(int index) { 
    return new Exp(
     myDCList[index]['dname'], 
     _getChildren(myDCList[index]['did']), 
    ); 
    //return new Specialties.fromMap(mylist[index]); 

    } 
} 

class Exp { 
    Exp(this.title, [this.children]); 
    final String title; 
    final Future<List<Exp>> children; 
} 


class ListChild extends StatefulWidget { 
    ListChild({Key key, this.exp}) : super(key: key); 

    final Exp exp; 
    @override 
    State createState() => new ListChildState(); 
} 

class ListChildState extends State<ListChild> { 
    //PageStorageKey<ListChildState> _key = new PageStorageKey(ListChild); 
    @override 
    Widget build(BuildContext context) { 
    return new ExpansionTile(
     key: new PageStorageKey(ListChild), 
     title: new Text(widget.exp.title), 
     children: <Widget>[ 
     new Text(widget.exp.children.title), 
     ], 
    ); 
    } 
} 
+0

能否請你刪除最後一個編輯,做一個新的問題?否則沒有人會知道這個問題實際上是什麼。 –

+0

對不起,我刪除並添加了另一個問題。 – Robert

回答

2

對您提出意見和編輯的反應我冒昧地寫了一個工作示例。隨意編輯或評論。我希望,這是你想達到的。

import 'dart:async'; 

import 'package:flutter/material.dart'; 
import 'package:http/http.dart' as http; 
import 'dart:convert'; 

void main() { 
    runApp(new MyApp()); 
} 

class MyApp extends StatelessWidget { 
    @override 
    Widget build(BuildContext context) { 
    return new MaterialApp(
     title: 'ExpansionTile Test', 
     home: new MyHomePage(), 
    ); 
    } 
} 

class MyHomePage extends StatefulWidget { 
    @override 
    _MyHomePageState createState() => new _MyHomePageState(); 
} 

class _MyHomePageState extends State<MyHomePage> { 
    Future<http.Response> _responseFuture; 

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

    @override 
    Widget build(BuildContext context) { 
    return new Scaffold(
     appBar: new AppBar(
     title: new Text('ExpansionTile Test'), 
    ), 
     body: 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); 
      } 
     }, 
    ), 
    ); 
    } 
} 

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; 

    @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), 
     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); 
       List<Widget> reasonList = []; 
       json.forEach((element) { 
       reasonList.add(new ListTile(
        dense: true, 
        title: new Text(element['reason']), 
       )); 
       }); 
       return new Column(children: reasonList); 
      } 
      }, 
     ) 
     ], 
    ); 
    } 
} 

Screenshot of the app

+0

這工作完美,我甚至沒有接近或採取一個壞的方法。謝謝你的幫助。 – Robert

0

我認爲解決這個最好的方法是使用一個FutureBuilder(也許在this answer看看)。我將爲ExpansionTile標題實施一個FutureBuilder,併爲每個ExpansionTile正文實施第二個。
上述鏈接答案中的示例可以非常適合您的用例。

如果您需要更多幫助,只需留言,我會盡力爲您實施一個示例。

+0

我用我編寫並嘗試使用的代碼更新了我的帖子。有任何想法嗎? – Robert