flutter入門之通過GridView和PageView實現展示item的功能

    【原創不易,轉載請註明出處:https://blog.csdn.net/email_jade/article/details/87915598

    今天給大家帶來的是一個非常常見的佈局,通過GridViewPageView實現類似於聊天表情emoji佈局的功能,我們先來看一下效果吧:

    看了標題大家應該清楚,組成該佈局的主體元素是GridViewPageView

    我們來分解一下佈局,佈局見上下兩部分,上面的圖標和下面的頁指示器,頁指示器比較簡單,一個居中的Row佈局搞定,如下,其中_pageCount代表總頁數:

  ///頁標
  Widget _buildCursor() {
    List<Widget> list = List();
    for (int i = 0; i < _pageCount; i++) {
      list.add(_buildPoint(_currentPage == i));
    }
    return Container(
      child: Row(
        children: list,
        mainAxisSize: MainAxisSize.min,
      ),
      alignment: AlignmentDirectional.center,
    );
  }

  ///單個點
  Widget _buildPoint(bool focus) {
    return Padding(
      padding: EdgeInsets.all(10.0),
      child: Container(
          width: 10, height: 10, color: focus ? Colors.black : Colors.grey),
    );
  }

    圖標部分,單頁可以看做是一個GridView,而多個GridView又組成了一個PageView,由於翻頁的時候要聯動下面的頁指示器跟着改變,因此要使用到PageView的PageController動態改變頁數,代碼如下,要記得及時釋放controller:

    

  final List<Widget> children;
  final int column; //列數
  final int row; //行數
  final double columnSpacing; //列間隔
  final double rowSpacing; //行間隔
  final double itemRatio; //每個item的寬高比,默認正方形


  。。。。

   ///每頁的個數
  int _countPerPage;
  ///總頁數
  int _pageCount;
  ///當前頁
  int _currentPage;
  ///控制器
  PageController _controller;


  ///計算總頁數及單頁的item數目
  void _calculatePage() {
    assert(widget.children != null);
    _countPerPage = widget.row * widget.column;
    _pageCount = (widget.children.length / _countPerPage).ceil();
  }

  ///多個Item構建單頁的GridView
  Widget _buildGrid(List<Widget> list) {
    return GridView.count(
      crossAxisCount: widget.column,
      children: list,
      mainAxisSpacing: widget.rowSpacing,
      crossAxisSpacing: widget.columnSpacing,
      childAspectRatio: widget.itemRatio,
    );
  }

  ///構建多個GridView
  List<Widget> _buildPages() {
    List<Widget> list = List();
    int index = 0;
    int realIndex;
    for (int i = 0; i < _pageCount; i++) {
      realIndex = index + _countPerPage > widget.children.length
          ? widget.children.length
          : index + _countPerPage;
      List l = widget.children.sublist(index, realIndex);
      index = realIndex;
      list.add(_buildGrid(l));
    }
    return list;
  }

  ///多個GridView構建PageView
  Widget _buildPageView() {
    return PageView(
      controller: _controller,
      children: _buildPages(),
      onPageChanged: (page) {
        setState(() {
          _currentPage = page;
        });
      },
    );
  }

   

    佈局已經完成,比較簡單。當然,其實有很多內容可以擴展,比如可以通過Container的BoxDecoration shape屬性shape: BoxShape.circle改變頁指示器爲圓形,也可以通過修改item動態改變樣式,比如說是圖片和標題組成的Item,等等,都由實際情況來決定,只要大體結構不變,就可以使用此模塊。

    下面是使用部分,演示的時候用到了fluttertoast控件:

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: GridPage(children: _buildChildren(), column: 7, row: 4,),
    );
  }

  ///構建數據
  List<Widget> _buildChildren(){
    List<Widget> list = List();
    for(int i=0; i<133; i++){
      list.add(GestureDetector(child:Icon(Icons.android, color: Colors.green, size: 40.0,), onTap: (){
        Fluttertoast.showToast(msg: "item $i on click");
      },),);
    }
    return list;
  }
}

     完整代碼見:

     https://github.com/jadennn/flutter_grid_page

     flutter很好,路還很長,讓我們一起奮鬥前行!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章