2017-08-01 14 views
1

expansionTileリストを動的に構築するためのガイダンスを探しています。私は、成功したListviewをjson APIから動的に構築しましたが、expansionTileを構築する上での例は見つかりませんでした。トップレベルを戻す1つのAPIコールと、拡張リストを戻すための各トップレベルのコールがあります。誰でもこの例がありますか?私は静的な例を見つけましたが、動的にする方法を明確にしていません。flutter dynamic expansionTile

ここに私が思いついたコードがあります。私はタイルのタイトル部分を見ることができ、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

私はこれに対処する最善の方法は、(多分this answerを見て)FutureBuilderを使用することだと思います。私はExpansionTileタイトルのために1つのFutureBuilderを実装し、各ExpansionTileボディのために2つ目のFutureBuilderを実装します。
上記のリンクされた回答の例は、使用例に非常によく適合している可能性があります。

もっと助けが必要な場合は、ただ叫ぶだけで、私はあなたのための例を実装しようとします。

+0

私は書いたコードを使用して私のポストを更新しました。何か案は? – Robert

関連する問題