반응형
flutter 작업 중에 API를 통한 위치조회 서비스를 제작중에 나온 코드를 공유겸 올립니다.
import 'dart:async'; import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(), ); } } class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { final StreamController<String> _streamSearch = StreamController<String>(); FocusNode textFocus = FocusNode(); final myController = TextEditingController(); @override initState() { super.initState(); } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("StreamBuilder test"), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[ TextField( controller: myController, keyboardType: TextInputType.text, focusNode: textFocus, onChanged: (text) { _streamSearch.add(text); }, decoration: const InputDecoration( labelText: 'Input', ), ), Stack( children: [ StreamBuilder( stream: _streamSearch.stream, builder: (context, snapshot) { if (snapshot.hasData == true) { return FutureBuilder( future: fetchSearch(snapshot.data.toString()), builder: (context, AsyncSnapshot snaps) { if (snaps.hasData == true) { return Container( height: 250, child: ListView.builder( shrinkWrap: true, itemCount: snaps.data.length, itemExtent: 50, //each rows height itemBuilder: (context, index) { return ListTile( onTap: () => { textFocus.unfocus(), _streamSearch.add(''), myController.text = '', print('detail : ${snaps.data[index].place} ${snaps.data[index].x} ${snaps.data[index].y}'), }, // leading: // Text('${snaps.data[index].place}'), title: Text('${snaps.data[index].place}'), trailing: const Icon( Icons.location_pin, color: Colors.blue, size: 30.0, ), ); }, ), //Text('test : ${snaps.data[1].title}'), ); } else { return Container(); } }, ); } else { return Container(); } }, ), ], ), ], ), ), ); } } class getPostList { final List<Post> entries; getPostList(this.entries); @override Widget build(BuildContext context) { return ListView.builder( padding: const EdgeInsets.all(8), itemCount: entries.length, itemBuilder: (BuildContext context, int index) { return Container( height: 50, child: Center(child: Text('Entry ${entries[index].place}')), ); }, ); } } Future<List<Post>> fetchSearch(String name) async { String x = '128.5'; String y = '36.5'; String url = 'https://api.fixid.kr/get_geo.php?type=addrList&addr=$name&x=$x&y=$y'; print(url); final response = await http.get(Uri.parse(url)); if (response.statusCode == 200) { // 만약 서버가 OK 응답을 반환하면, JSON을 파싱합니다. //print(json.decode(response.body)); //return Post.fromJSON(json.decode(response.body)); final parsed = json.decode(response.body).cast<Map<String, dynamic>>(); return parsed.map<Post>((json) => Post.fromJson(json)).toList(); } else { // 만약 응답이 OK가 아니면, 에러를 던집니다. throw Exception('Failed to load post'); } } class Post { final String place; final String x; final String y; Post({required this.place, required this.x, required this.y}); factory Post.fromJson(Map<String, dynamic> json) { return Post(place: json['place'], x: json['x'], y: json['y']); } } |
반응형