天天看點

Flutter中常用的清單元件

如果想去掉widget預設的padding,需要用MediaQuery.removePadding包裹

MediaQuery.removePadding(context: context,
    removeTop: true,
    child:widget)
           

基于ExpansionTile實作可展開的清單,相等于Android中的ExpandableListView

class SearchPage extends StatefulWidget{

  @override
  State<StatefulWidget> createState() => _SearchState();
}
class _SearchState extends State<SearchPage>{
  var map = {
    "北京":["東城區","西城區","朝陽區","海澱區","豐台區"],
    "上海":["浦東區","虹口區","靜安寺區"],
    "山東":["濟南","青島","濰坊","煙台","聊城"]
  };
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("搜尋"),),
      body: ListView(
        children: _buildCity()
      )
    );
  }
  List<Widget> _buildCity(){
    List<Widget> widgets = [];
    map.keys.forEach((key){
      widgets.add(_buildSubCity(map[key],key));
    });
    return widgets;
  }
  Widget _buildSubCity(List<String> subCities,String city){
    return ExpansionTile(
        title: Text(city),
        initiallyExpanded:false,
        children: subCities.map((title)=>_buildItem(title)).toList()
    );
  }
  Widget _buildItem(String title){
    return FractionallySizedBox(
      widthFactor: 1,
      child: Container(
        height: 50,
        alignment: Alignment.centerLeft,
        child: Text(title),
        color: Colors.lightBlue,
        margin: EdgeInsets.only(top: 5),
      ),
    );
  }
}
           

基于GridView實作網格清單

class TravelPage extends StatefulWidget{
  @override
  State<StatefulWidget> createState() => _TravelState();
}
const CITY_NAMES = ['北京','上海','廣州','深圳','杭州','蘇州','天津','重慶','青島','煙台','大連','哈爾濱'];
class _TravelState extends State<TravelPage>{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("旅拍"),),
      body: GridView.count(
          crossAxisCount: 2,
          children: _buildItems(),
      )
    );
  }
  List<Widget> _buildItems(){
    List<Widget> widgets = [];
    for(int i = 0 ; i < CITY_NAMES.length; i++){
      widgets.add(_buildItem(CITY_NAMES[i],i));
    }
    return widgets;
  }

  Widget _buildItem(String city,int position){
    return Container(
      height: 80,
      decoration: BoxDecoration(color: Colors.teal),
      margin: EdgeInsets.only(bottom: 5, right: position % 2 == 0 ? 2.5 : 0,left: position % 2 == 0 ? 0 : 2.5),
      alignment: Alignment.center,
      child: Text(city,
        style: TextStyle(color: Colors.white,fontSize: 20),
      ),
    );
  }
}
           

進階功能清單下拉重新整理和上拉加載更多功能的實作

下拉重新整理的實作

1.使用RefreshIndicator包裹ListView

2.實作RefreshIndicator的onRefresh方法

上拉加載更多的實作:

1.為ListView設定一個ScrollController

2.為ScrollController在initState方法中添加一個監聽:ScrollController.addListener((){});

3.在addListener中判斷是否滑動到最下方(ScrollController.positon.pixels == ScrollController.position.maxScrollExtent)如果為true就執行loadMore方法

class MyPage extends StatefulWidget{
  @override
  State<StatefulWidget> createState() => _MyState();
}
const CITIES = ['北京','上海','廣州','深圳','杭州','蘇州','天津','重慶','青島','煙台','大連','哈爾濱','洛陽','無錫'];
class _MyState extends State<MyPage>{
  var cities = List<String>.from(CITIES);
  var _scrollController = ScrollController();

  @override
  void initState() {
    super.initState();
    _scrollController.addListener((){
      print(_scrollController.position);
      print(_scrollController.position.pixels);
      if(_scrollController.position.pixels == _scrollController.position.maxScrollExtent){
        _onLoadMore();
        print("on load more");
      }
    });
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }

  Future<Null> _onLoadMore() async{
    await Future.delayed(Duration(milliseconds: 500));
    setState(() {
      cities.add("load more");
    });
    return null;
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("我的"),),
        body: RefreshIndicator(child: ListView(
          controller: _scrollController,
          children: _buildItems(),
        ), onRefresh: _onRefresh)
    );
  }
  List<Widget> _buildItems(){
    return cities.map((city)=>_buildItem(city)).toList();
  }

  Widget _buildItem(String city) {
    return Container(
      height: 40,
      decoration: BoxDecoration(color: Colors.teal),
      margin: EdgeInsets.only(bottom: 5,),
      alignment: Alignment.center,
      child: Text(city,
        style: TextStyle(color: Colors.white, fontSize: 20),
      ),
    );
  }

  Future<Null> _onRefresh() async{
    await Future.delayed(Duration(milliseconds: 2000));
    setState(() {
      cities = cities.reversed.toList();
    });
    return null;
  }
}
           

繼續閱讀