为了账号安全,请及时绑定邮箱和手机立即绑定

Flutter 城市列表 索引&悬停

标签:
Android iOS 开源

[QuickSelectListView]

包含有悬停效果ListView,索引 IndexBar,触摸IndexBar Tag滚动到指定item。QuickSelectListView是通过IndexBar与SuspensionListView封装,可以快速实现城市列表效果。源码已经开源到flutterchina flukit组件库中,欢迎star。

一、城市名转拼音

Flutter版汉字转拼音库已经为大家写好了, lpinyin 欢迎star

二、IndexBar

索引IndexBar

三、SuspensionListView

带有悬停效果View

Demo截图

cityselect

Android扫码下载APK

flutter_demos

Example

 class CitySelectPage extends StatefulWidget {
  final String title;
  CitySelectPage(this.title);
  @override
  State<StatefulWidget> createState() {
    return new _CitySelectPageState();
  }
}

class _CitySelectPageState extends State<CitySelectPage> {
  List<CityInfo> _cityList = List();
  List<CityInfo> _hotCityList = List();

  int _suspensionHeight = 40;
  int _itemHeight = 50;
  String _suspensionTag = "";

  @override
  void initState() {
    super.initState();
    _hotCityList.add(CityInfo(name: "北京市", tagIndex: "热门"));
    _hotCityList.add(CityInfo(name: "广州市", tagIndex: "热门"));
    _hotCityList.add(CityInfo(name: "成都市", tagIndex: "热门"));
    _hotCityList.add(CityInfo(name: "深圳市", tagIndex: "热门"));
    _hotCityList.add(CityInfo(name: "杭州市", tagIndex: "热门"));
    _hotCityList.add(CityInfo(name: "武汉市", tagIndex: "热门"));

    loadData();
  }

  void loadData() async {
    //加载城市列表
    rootBundle.loadString('assets/data/china.json').then((value) {
      Map countyMap = json.decode(value);
      List list = countyMap['china'];
      list.forEach((value) {
        _cityList.add(CityInfo(name: value['name']));
      });
      _handleList(_cityList);

      setState(() {
        _suspensionTag = _hotCityList[0].getSuspensionTag();
      });
    });
  }

  void _handleList(List<CityInfo> list) {
    if (list == null || list.isEmpty) return;
    for (int i = 0, length = list.length; i < length; i++) {
      String pinyin =
          PinyinHelper.convertToPinyinStringWithoutException(list[i].name);
      String tag = pinyin.substring(0, 1).toUpperCase();
      list[i].namePinyin = pinyin;
      if (RegExp("[A-Z]").hasMatch(tag)) {
        list[i].tagIndex = tag;
      } else {
        list[i].tagIndex = "#";
      }
    }
  }

  void _onSusTagChanged(String tag) {
    setState(() {
      _suspensionTag = tag;
    });
  }

  ///构建悬停Widget.
  Widget _buildSusWidget(String susTag) {
    return Container(
      height: _suspensionHeight.toDouble(),
      padding: const EdgeInsets.only(left: 15.0),
      color: Color(0xfff3f4f5),
      alignment: Alignment.centerLeft,
      child: Text(
        '$susTag',
        softWrap: false,
        style: TextStyle(
          fontSize: 14.0,
          color: Color(0xff999999),
        ),
      ),
    );
  }

  ///构建列表 item Widget.
  Widget _buildListItem(CityInfo model) {
    return Column(
      children: <Widget>[
        Offstage(
          offstage: !(model.isShowSuspension == true),
          child: _buildSusWidget(model.getSuspensionTag()),
        ),
        SizedBox(
          height: _itemHeight.toDouble(),
          child: ListTile(
            title: Text(model.name),
            onTap: () {
              print("OnItemClick: $model");
              Navigator.pop(context, model);
            },
          ),
        )
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: new AppBar(
          title: new Text(widget.title),
          centerTitle: true,
        ),
        body: new Column(
          children: <Widget>[
            Container(
              alignment: Alignment.centerLeft,
              padding: const EdgeInsets.only(left: 15.0),
              height: 50.0,
              child: Text("当前城市: 成都市"),
            ),
            Expanded(
                flex: 1,
                child: QuickSelectListView(
                  data: _cityList,
                  topData: _hotCityList,
                  itemBuilder: (context, model) => _buildListItem(model),
                  suspensionWidget: _buildSusWidget(_suspensionTag),
                  isUseRealIndex: true,
                  itemHeight: _itemHeight,
                  suspensionHeight: _suspensionHeight,
                  onSusTagChanged: _onSusTagChanged,
                ))
          ],
        ));
  }
}
点击查看更多内容
3人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消