SliverAppBar

CustomScrollView 中能实现一些 滚动的效果:这里请出你们的 女神 ‘伊琳格娃’

page_sliver_list.dart

import 'dart:convert' as convert;

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class PageSliverList extends StatefulWidget {
  const PageSliverList({Key? key}) : super(key: key);

  @override
  _PageSliverListState createState() => _PageSliverListState();
}

class _PageSliverListState extends State<PageSliverList> {
  List<CountryInfo> _countryArray = [];
  List<Map> items = [
    {'title': 'A', 'color': Colors.green, 'pinned': true},
    {'title': 'B', 'color': Colors.red, 'pinned': true},
    {'title': 'C', 'color': Colors.blue, 'pinned': true},
    {'title': 'D', 'color': Colors.amberAccent, 'pinned': true},
    {'title': 'E', 'color': Colors.deepOrangeAccent, 'pinned': true},
    {'title': 'F', 'color': Colors.cyan, 'pinned': true},
  ];

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _request();
  }

  @override
  Widget build(BuildContext context) {
    final args = ModalRoute.of(context)!.settings.arguments as Map;
    return Scaffold(
      appBar: AppBar(
        title: Text(args['title']),
      ),
      body: CustomScrollView(
        slivers: _buildSliver(),
        // slivers: [
        //   // SliverToBoxAdapter(
        //   //   child: Container(
        //   //     color: Colors.deepOrangeAccent,
        //   //     height: 50,
        //   //     child: Text("A"),
        //   //   ),
        //   // ),
        //   SliverPersistentHeader(
        //     delegate: _DelegateSliverPersistent(
        //       title: 'A',
        //       color: Colors.deepOrangeAccent,
        //     ),
        //     pinned: true,
        //     floating: false,
        //   ),
        //
        //   _buildSliverItem('A'),
        //   SliverPersistentHeader(
        //     delegate: _DelegateSliverPersistent(
        //       title: 'B',
        //       color: Colors.greenAccent,
        //     ),
        //     pinned: true,
        //     floating: false,
        //   ),
        //   _buildSliverItem('B'),
        //   SliverPersistentHeader(
        //     delegate: _DelegateSliverPersistent(
        //       title: 'C',
        //       color: Colors.pinkAccent,
        //     ),
        //     pinned: true,
        //     floating: false,
        //   ),
        //   _buildSliverItem('C'),
        //   SliverPersistentHeader(
        //     delegate: _DelegateSliverPersistent(
        //       title: 'D',
        //       color: Colors.lightBlueAccent,
        //     ),
        //     pinned: true,
        //     floating: false,
        //   ),
        //   _buildSliverItem('D'),
        //   SliverPersistentHeader(
        //     delegate: _DelegateSliverPersistent(
        //       title: 'E',
        //       color: Colors.orange,
        //     ),
        //     pinned: true,
        //     floating: false,
        //   ),
        //   _buildSliverItem('E'),
        //   SliverPersistentHeader(
        //     delegate: _DelegateSliverPersistent(
        //       title: 'F',
        //       color: Colors.green,
        //     ),
        //     pinned: true,
        //     floating: false,
        //   ),
        //   _buildSliverItem('F'),
        // ],
      ),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.refresh),
        onPressed: () {
          setState(() {
            _countryArray.clear();
          });
          _request();
        },
      ),
    );
  }

  _request() async {
    const String url = 'https://m.gbm001.com/area/country/getAllCountry?type=2';
    final res = await http.get(Uri.parse(url));
    if (res.statusCode != 200) {
      throw ('http error, code ${res.statusCode}');
    }

    final json = convert.jsonDecode(res.body)['data'];

    final List<CountryInfo> countryArray = [];
    json.forEach(
      (item) {
        countryArray.add(CountryInfo(
          countryNameZh: item['countryNameZh'],
          countryId: item['countryId'],
          flagImgUrl: item['flagImgUrl'],
        ));
      },
    );
    setState(() => _countryArray = countryArray);

// print(json);
  }

  _buildSliverItem(String str) {
    final List<CountryInfo> list = _countryArray
        .where((element) => element.countryId.startsWith(str))
        .toList();
    return SliverGrid(
      delegate: SliverChildBuilderDelegate(
        (BuildContext context, int index) {
          return InkWell(
            onTap: () {
              Navigator.pushNamed(context, "/page_sliver_detail",
                  arguments: list);
            },
            child: Column(
              children: [
                CircleAvatar(
                  backgroundColor: Colors.white,
                  child: ClipOval(
                    child: Image.network(
                      list[index].flagImgUrl,
                      fit: BoxFit.cover,
                      width: 40,
                      height: 40,
                    ),
                  ),
                ),
                FittedBox(
                  child: Text(list[index].countryNameZh),
                )
              ],
            ),
          );

          // return ListTile(
          //   title: Text(list[index].countryNameZh),
          //   subtitle: Text(list[index].countryId),
          //   leading: CircleAvatar(
          //     backgroundColor: Colors.white,
          //     child: ClipOval(
          //       child: Image.network(
          //         list[index].flagImgUrl,
          //         fit: BoxFit.cover,
          //         width: 40,
          //         height: 40,
          //       ),
          //     ),
          //   ),
          //   trailing: Icon(Icons.keyboard_arrow_right_outlined),
          // );
        },
        childCount: list.length,
      ),
      gridDelegate:
          SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 4),
    );

    // return SliverList(
    //   delegate: SliverChildBuilderDelegate(
    //     (BuildContext context, int index) {
    //       return ListTile(
    //         title: Text(list[index].countryNameZh),
    //         subtitle: Text(list[index].countryId),
    //         leading: CircleAvatar(
    //           backgroundColor: Colors.white,
    //           child: ClipOval(
    //             child: Image.network(
    //               list[index].flagImgUrl,
    //               fit: BoxFit.cover,
    //               width: 40,
    //               height: 40,
    //             ),
    //           ),
    //         ),
    //         trailing: Icon(Icons.keyboard_arrow_right_outlined),
    //       );
    //     },
    //     childCount: list.length,
    //   ),
    // );
  }

  _buildSliver() {
    List<Widget> widgetArray = [];
    for (var element in items) {
      widgetArray.addAll([
        SliverPersistentHeader(
          delegate: _DelegateSliverPersistent(
            element: element,
          ),
          pinned: element['pinned'],
          floating: false,
        ),
        _buildSliverItem(element['title']),
      ]);
    }
    return widgetArray;
    // items.map((e) {
    //   return [
    //     SliverPersistentHeader(
    //       delegate: _DelegateSliverPersistent(
    //         title: 'A',
    //         color: Colors.deepOrangeAccent,
    //       ),
    //       pinned: true,
    //       floating: false,
    //     ),
    //     _buildSliverItem('A'),
    //   ];
    // }).toList(),
  }
}

class _DelegateSliverPersistent extends SliverPersistentHeaderDelegate {
  final Map element;
  _DelegateSliverPersistent({required this.element});

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    print(
        '_DelegateSliverPersistent title${element['color']};  title${element['title']};  overlapsContent:$overlapsContent');
    return Container(
      color: element['color'],
      height: 50,
      child: Text(element['title']),
    );
  }

  @override
  // TODO: implement maxExtent
  double get maxExtent => 50;
  @override
  // TODO: implement minExtent
  double get minExtent => 50;

  @override
  bool shouldRebuild(covariant _DelegateSliverPersistent oldDelegate) {
    // TODO: implement shouldRebuild
    // return oldDelegate.title == title;
    return 50 != oldDelegate.maxExtent || 50 != oldDelegate.minExtent;
  }
}

class CountryInfo {
  final String countryNameZh;
  final String countryId;
  final String flagImgUrl;
  CountryInfo(
      {required this.countryNameZh,
      required this.countryId,
      required this.flagImgUrl});

  @override
  String toString() {
    // TODO: implement toString
    return 'countryNameZh:$countryNameZh ,countryId:$countryId';
  }
}

page_sliver_detail.dart

import 'package:flutter/material.dart';
import 'package:flutter_sliver/pages/subPages/page_sliver_list.dart';

class PageSliverDetail extends StatefulWidget {
  const PageSliverDetail({Key? key}) : super(key: key);

  @override
  _PageSliverDetailState createState() => _PageSliverDetailState();
}

class _PageSliverDetailState extends State<PageSliverDetail> {
  @override
  Widget build(BuildContext context) {
    final List<CountryInfo> args =
        ModalRoute.of(context)!.settings.arguments as List<CountryInfo>;
    return Scaffold(
      // appBar: AppBar(
      //   centerTitle: true,
      //   title: const Text("Sliver Detail"),
      // ),
      body: CustomScrollView(
        physics: const BouncingScrollPhysics(),
        slivers: [
          SliverAppBar(
            expandedHeight: 200,
            centerTitle: true,
            // title: Text("nihao"),
            floating: false,
            pinned: true,
            snap: false,
            stretch: true,
            onStretchTrigger: () async {
              print('onStretchTrigger');
              return;
            },
            flexibleSpace: FlexibleSpaceBar(
              title: Text("nihao"),
              background: Image.network(
                'http://cdn.max-c.com/heybox/dailynews/img/343ab5e0f8489978c6bab49ef73daac6.jpg',
                fit: BoxFit.cover,
              ),
              collapseMode: CollapseMode.parallax,
            ),
          ),
          SliverList(
              delegate: SliverChildListDelegate(
            _buildInfo(args),
          ))
        ],
      ),
    );
  }

  _buildInfo(List<CountryInfo> args) {
    return args
        .map((e) => Card(
              child: Row(
                children: [
                  CircleAvatar(
                    child: ClipOval(
                      child: Image.network(
                        e.flagImgUrl,
                        width: 50,
                        height: 50,
                      ),
                    ),
                  ),
                  Padding(
                    padding: EdgeInsets.only(left: 10),
                    child: Text(e.countryNameZh),
                  ),
                ],
              ),
            ))
        .toList();
  }
}

猜你喜欢

转载自blog.csdn.net/nicepainkiller/article/details/122330541
今日推荐