實現點選"換一批"來切換內容,flutter之CustomScrollView【flutter20個例項之八】

蔥頭來過發表於2021-08-17

一、老套路,先看樣式

左圖是我業務中的樣式,右圖是下方原始碼展示樣式(複製可直接執行,無額外元件引入)

二、講解

1.涉及元件

首先,沒有一個單一元件來實現這個效果

實現這個效果涉及以下元件:

AppBar:頂端欄,一個最基本的軟體

Text:文字

Container:佈局元件

CustomScrollView:自定義滾動效果元件,比如列表和網格元件都可以包含在其中

SliverGrid:網格檢視元件

SliverList:列表控制元件

InkWell:效果控制元件,可以給其他widget包裹一個點選效果

ListTile:標題元件,通常填充listview
複製程式碼

2.首先設定下標題樣式

getItem是我們的主內容

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          leading: new IconButton(
            icon: new Icon(Icons.arrow_back,
                color: Colors.black38),
            onPressed: () {
              print('返回按鈕');
            },
          ),
          title: Text('換一批效果'),
          centerTitle: true,
          elevation: 0.0,
          actions: <Widget>[
            IconButton(
              icon: Icon(Icons.save),
              onPressed: () {},
            ),
          ],
        ), //這個是頂部tab樣式,如果不需要可以去掉
        body: Container(
          child: getItem(),
        ));
  }
複製程式碼

3.換一批點選效果

我們給換一批樣式設定一個點選效果

當點選的時候,判斷當前內容是否滿足18條(一屏展示的數目)

如果不滿足,說明最後一頁了,重置頁碼為1

如果滿足,說明當前資料>=18,後面可能還有資料,頁碼+1

然後請求資料,_getData()是封裝的一個請求資料函式

      SliverList(
        delegate: SliverChildListDelegate([
          ListTile(
            onTap: () {
              int Temp = page + 1;
              if (_list.length < 18) {
                Temp = 1;
              }
              setState(() {
                page = Temp;
              });
              _getData();
            },
            title: Text(
              '挑選一個圖示吧',
              style: TextStyle(color: Colors.black, fontSize: 12),
            ),
            trailing: Text('換一批',
                style: TextStyle(color: Colors.black54, fontSize: 10)),
          ),
        ]),
      ),
複製程式碼

4.網格內容其實就是一個SliverGrid,切換資料後,進行了部分頁面重新渲染

三、原始碼(可直接執行除錯)

import 'package:flutter/material.dart';

class AddHabit extends StatefulWidget {
  String hid = '';
  AddHabit({this.hid});
  @override
  _AddHabitState createState() => _AddHabitState();
}

class _AddHabitState extends State<AddHabit> {
  var _icon = '';
  double leftPadding = 15.0;
  List _list = [
    {
      'id': 1,
      'image':
          'https://daybili.oss-cn-beijing.aliyuncs.com/image/202008/liaotian.png'
    }
  ];
  int page = 1;

  @override
  void initState() {
    super.initState();
    this._getData();
  }

  //獲取資料, 為了測試方便, 我處理為了靜態資料
  _getData() async {
    //_list資料應該是通過網路請求獲得
    print(_list);
    setState(() {
      _list = _list;
    });
  }

  //build初始化
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          leading: new IconButton(
            icon: new Icon(Icons.arrow_back, color: Colors.black38),
            onPressed: () {
              print('返回按鈕');
            },
          ),
          title: Text('換一批效果'),
          centerTitle: true,
          elevation: 0.0,
          actions: <Widget>[
            IconButton(
              icon: Icon(Icons.save),
              onPressed: () {},
            ),
          ],
        ), //這個是頂部tab樣式,如果不需要可以去掉
        body: Container(
          child: getItem(),
        ));
  }

  //核心內容
  Widget getItem() {
    return CustomScrollView(slivers: <Widget>[
      SliverList(
        delegate: SliverChildListDelegate([
          ListTile(
            onTap: () {
              int Temp = page + 1;
              if (_list.length < 18) {
                Temp = 1;
              }
              setState(() {
                page = Temp;
              });
              _getData();
            },
            title: Text(
              '挑選一個圖示吧',
              style: TextStyle(color: Colors.black, fontSize: 12),
            ),
            trailing: Text('換一批',
                style: TextStyle(color: Colors.black54, fontSize: 10)),
          ),
        ]),
      ),
      SliverGrid(
        //padding: EdgeInsets.zero,
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 6, crossAxisSpacing: 5, mainAxisSpacing: 3),
        delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
          return habitIcon(_list[index]);
        }, childCount: _list.length),
      ),
    ]);
  }

  //某個圖示樣式
  Widget habitIcon(item) {
    return InkWell(
      onTap: () {
        setState(() {
          _icon = item['id'];
        });
      },
      child: Container(
        height: 100,
        width: 100,
        color: item['id'] == _icon ? Colors.white : Colors.black12,
        alignment: Alignment.center,
        child: Image.network(
          item['image'],
          width: 30,
          height: 30,
        ),
      ),
    );
  }
}
複製程式碼

相關文章