| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- import 'dart:convert';
- import 'dart:ui' as ui show window;
- import 'package:flutter/cupertino.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter/services.dart';
- import 'package:twong/utils/index.dart';
- class AddressSelecter extends StatefulWidget {
- final String title;
- final Function(String province, String city, String county, int code) onSelected;
- final Color unselectedColor;
- final Color selectedColor;
- final double itemTextFontSize;
- final TextStyle titleTextStyle;
- AddressSelecter(
- {Key key,
- @required this.onSelected,
- this.title,
- this.unselectedColor: Colors.grey,
- this.selectedColor: Colors.blue,
- this.itemTextFontSize: 14.0,
- this.titleTextStyle: const TextStyle(
- fontSize: 16.0, color: Colors.black, fontWeight: FontWeight.bold)})
- : super(key: key);
- @override
- createState() => _AddressSelecterState();
- }
- class _AddressSelecterState extends State<AddressSelecter>
- with TickerProviderStateMixin {
- int _index = 0;
- TabController _tabController;
- ScrollController _controller;
- /// TabBar不能动态加载,所以初始化3个,其中两个文字置空,点击事件拦截住。
- List<Tab> myTabs = <Tab>[Tab(text: '请选择'), Tab(text: ''), Tab(text: '')];
- List provinces = [];
- List cities = [];
- List counties = [];
- /// 当前列表数据
- List mList = [];
- /// 三级联动选择的position
- var _positions = [0, 0, 0];
- double itemHeight = 48.0;
- @override
- void initState() {
- super.initState();
- _controller = ScrollController();
- _tabController = TabController(vsync: this, length: myTabs.length);
- _initData();
- }
- @override
- void dispose() {
- _tabController?.dispose();
- _controller?.dispose();
- super.dispose();
- }
- @override
- Widget build(BuildContext context) {
- return Material(
- color: Colors.white,
- child: SafeArea(
- child: Container(
- height:
- MediaQueryData.fromWindow(ui.window).size.height * 9.0 / 16.0,
- child: Column(children: <Widget>[
- Stack(children: <Widget>[
- Container(
- width: double.infinity,
- alignment: Alignment.center,
- padding: const EdgeInsets.symmetric(vertical: 16.0),
- child:
- Text("${widget.title}", style: widget.titleTextStyle)),
- Positioned(
- right: 0,
- child: IconButton(
- icon: Icon(Icons.close, size: 22),
- onPressed: () => Navigator.maybePop(context)))
- ]),
- _line,
- Container(
- color: Colors.white,
- alignment: Alignment.centerLeft,
- child: TabBar(
- controller: _tabController,
- isScrollable: true,
- onTap: (index) {
- if (myTabs[index].text.isEmpty) {
- _tabController.animateTo(_index);
- return;
- }
- switch (index) {
- case 0:
- mList = provinces;
- break;
- case 1:
- mList =
- cities = provinces[_positions[0]]['c'];
- break;
- case 2:
- mList =
- counties = cities[_positions[1]]['c'];
- break;
- }
- setState(() {
- _index = index;
- _controller.animateTo(_positions[_index] * itemHeight,
- duration: Duration(milliseconds: 10),
- curve: Curves.ease);
- });
- },
- indicatorSize: TabBarIndicatorSize.label,
- unselectedLabelColor: Colors.black,
- labelColor: widget.selectedColor,
- tabs: myTabs)),
- _line,
- Expanded(
- child: provinces.length > 0
- ? _buildListView()
- : CupertinoActivityIndicator(animating: false))
- ])),
- ));
- }
- void _initData() async {
- // rootBundle.loadString('assets/area.json').then((value) {
- // provinces = json.decode(value);
- // setState(() => mList = provinces);
- // });
- var data = Cache.loadString(SaveKey.areas);
- if(data == null) {
- Request.get("city_list").then((res) {
- provinces = res;
- Cache.saveString(SaveKey.areas, json.encode(res));
- setState(() {
- mList = provinces;
- });
- });
- Log.d("load area from network");
- } else {
- provinces = json.decode(data);
- setState(() {
- mList = provinces;
- });
- Log.d("load area from cache");
- }
- setState(() {});
- }
- Widget _buildListView() {
- return ListView.builder(
- controller: _controller,
- itemBuilder: (context, index) => InkWell(
- child: Container(
- padding: EdgeInsets.symmetric(horizontal: 16.0),
- height: itemHeight,
- alignment: Alignment.centerLeft,
- child: Row(children: <Widget>[
- Text(mList[index]["n"],
- style: TextStyle(
- fontSize: widget.itemTextFontSize,
- color: mList[index]["n"] == myTabs[_index].text
- ? widget.selectedColor
- : widget.unselectedColor)),
- SizedBox(height: 8),
- Offstage(
- offstage: mList[index]["n"] != myTabs[_index].text,
- child: Icon(Icons.check,
- size: 16.0, color: widget.selectedColor))
- ])),
- onTap: () {
- myTabs[_index] = Tab(text: mList[index]["n"]);
- _positions[_index] = index;
- _index++;
- switch (_index) {
- case 1:
- mList = cities = provinces[_positions[0]]['c'];
- myTabs[1] = Tab(text: "请选择");
- myTabs[2] = Tab(text: "");
- break;
- case 2:
- mList = counties = cities[_positions[1]]['c'];
- myTabs[2] = Tab(text: "请选择");
- break;
- case 3:
- _index = 2;
- widget.onSelected(
- provinces[_positions[0]]["n"],
- cities[_positions[1]]["n"],
- counties[_positions[2]]["n"],
- counties[_positions[2]]["v"]);
- Navigator.maybePop(context);
- break;
- }
- setState(() {});
- _controller.animateTo(0.0,
- duration: Duration(milliseconds: 100), curve: Curves.ease);
- _tabController.animateTo(_index);
- }),
- itemCount: mList.length);
- }
- Widget _line = Container(height: 0.6, color: Color(0xFFEEEEEE));
- }
|