이번에 검색결과(도로명 주소)를 ListView 형식으로 화면에 표시해보겠습니다.
개발환경 : 윈도우11, 안드로이드 스튜디오, flutter 3.0.1
화면은 아래와 같습니다. 검색창에 단어를 입력하고 엔터 클릭시 검색결과 반환.
현재는 최대 100건만 표시하였다.
./src/screens/start/address_service.dart - 함수의 리턴 타입을 모델링 타입으로 변경함
Future<AddressModel> searchAddressByStr(String text) async {
final formData = {
'confmKey': jusoKey,
'currentPage': '1',
'countPerPage': '100',
'keyword': text,
'resultType': 'json',
};
var resp = await Dio()
.get('http://www.juso.go.kr/addrlink/addrLinkApi.do',
queryParameters: formData)
.catchError((e) {
logger.e(e.message);
});
AddressModel addressModel = AddressModel.fromJson(resp.data);
debugPrint(addressModel.results.common.toString());
debugPrint(addressModel.results.juso[0].toString());
// logger.d(resp.data is Map);
return addressModel;
}
./src/screens/start/address_page.dart - 함수의 리턴 타입을 모델링 타입으로 변경함
import 'package:extended_image/extended_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../../constants/common_size.dart';
import '../../models/address_model.dart';
import 'address_service.dart';
class AddressPage extends StatefulWidget {
const AddressPage({Key? key}) : super(key: key);
@override
State<AddressPage> createState() => _AddressPageState();
}
class _AddressPageState extends State<AddressPage> {
final TextEditingController _addressController = TextEditingController();
// 주소모델 객체 생성
AddressModel? _addressModel;
final _isGettingLocation = false;
@override
void dispose() {
_addressController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
debugPrint(">>> build from AddressPage");
return SafeArea(
// padding 대신에 minimum 으로 설정 가능, 위/아래 글씨가 잘리는것도 방지하자
minimum: const EdgeInsets.symmetric(horizontal: padding_16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
TextFormField(
controller: _addressController,
// 키보드 입력후 엔터 버튼 클릭시 검색 시작
onFieldSubmitted: onClickTextField,
decoration: InputDecoration(
prefixIcon: const Icon(
Icons.search,
color: Colors.grey,
),
// 아이콘 주변 공간을 조절 가능
prefixIconConstraints:
const BoxConstraints(minWidth: 24, maxHeight: 24),
// 문자 입력후 밑줄이 생기게 설정
border: const UnderlineInputBorder(
borderSide: BorderSide(color: Colors.grey)),
// focusedBorder: const UnderlineInputBorder(borderSide: BorderSide(color: Colors.grey)),
hintText: '도로명으로 검색...',
hintStyle: TextStyle(color: Theme.of(context).hintColor),
),
),
const SizedBox(height: padding_08),
TextButton.icon(
label: Text(
_isGettingLocation ? '위치 찾는중 ~~' : '현재위치 찾기',
style: Theme.of(context).textTheme.button,
),
onPressed: () {},
icon: _isGettingLocation
? const SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(color: Colors.white))
: const Icon(CupertinoIcons.compass,
color: Colors.white, size: 20),
),
Expanded(
child: ListView.builder(
padding: const EdgeInsets.symmetric(vertical: padding_16),
// 아이템 개수 설정
itemCount: (_addressModel == null)
? 0
: _addressModel!.results.juso.length,
itemBuilder: (context, index) {
if (_addressModel == null) {
return Container();
}
var subAddress = _addressModel!.results.juso[index].jibunAddr.split(' ');
debugPrint('[$index] ${subAddress.toString()}');
return ListTile(
// 도로명 주소 표시
title: Text(_addressModel!.results.juso[index].roadAddrPart1),
// 지번 주소 표시
subtitle: Text('${subAddress[2]} ${subAddress[3]}'),
);
},
),
),
],
),
);
}
// 주소 검색 함수 호출
void onClickTextField(text) async {
_addressModel = await AddressService().searchAddressByStr(text);
setState(() {});
}
}
'Flutter > 12 Clone 'Used Goods app'' 카테고리의 다른 글
[Flutter] Clone - 당근마켓13(Shared reference) (0) | 2022.07.25 |
---|---|
[Flutter] Clone - 당근마켓12(geocoding & reverse geocoding) (0) | 2022.07.24 |
[Flutter] Clone - 당근마켓10(Address Model) (0) | 2022.07.22 |
[Flutter] Clone - 당근마켓9(logout) (0) | 2022.07.21 |
[Flutter] Clone - 당근마켓8(authorization-login) (0) | 2022.07.21 |