import 'dart:async'; import 'dart:convert'; import 'dart:math'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:medicine_app/request_util.dart'; import 'package:medicine_app/search_page.dart'; import 'package:medicine_app/slide_page_route.dart'; import 'package:smooth_page_indicator/smooth_page_indicator.dart'; import 'medicine_detail_page.dart'; class HomePage extends StatefulWidget { HomePage({Key? key}) : super(key: key); @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).accentColor, elevation: 2, shadowColor: Theme.of(context).shadowColor, toolbarHeight: 50, title: TextButton( child: Row( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.search_sharp, size: 17, ), Text('搜索') ], ), style: ButtonStyle( foregroundColor: MaterialStateProperty.all(Colors.grey.shade500), shadowColor: MaterialStateProperty.all(Colors.transparent), overlayColor: MaterialStateProperty.all(Colors.transparent), minimumSize: MaterialStateProperty.all(Size.fromHeight(32)), backgroundColor: MaterialStateProperty.all(Colors.white24.withOpacity(0.80)), textStyle: MaterialStateProperty.all(TextStyle(fontSize: 13, letterSpacing: 2)), shape: MaterialStateProperty.all( RoundedRectangleBorder(borderRadius: BorderRadius.circular(16.0)), ), ), onPressed: () => Navigator.of(context).push(SlidePageRoute(builder: SearchMedicinePage())), ), ), body: FutureBuilder(future: Future.sync(() { return Request.getDio().get('/medicine/outlines'); }), builder: (BuildContext context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { Map data = json.decode(snapshot.data.toString()); final List medicineList = data['data']; return ListView.builder( cacheExtent: 10, padding: EdgeInsets.only(bottom: 30), itemCount: medicineList.length + 1, itemBuilder: (BuildContext context, int index) { if (index < medicineList.length) { final Map medicine = medicineList[index]; final List medicineDetails = medicine['details']; return Card( color: Colors.grey[10], shadowColor: Colors.grey[50], elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15), ), borderOnForeground: false, margin: EdgeInsets.symmetric(vertical: 5, horizontal: 5), // 外边距 child: Container( margin: EdgeInsets.symmetric(vertical: 5, horizontal: 5), height: 250, child: Column( children: [ Expanded( flex: 1, child: ListTile( title: Text( "${medicine['name']}", style: TextStyle(fontWeight: FontWeight.bold), )), ), Expanded( flex: 3, child: Builder(builder: (context) { final int pageCount = (medicineDetails.length / 6).ceil(); final int maxPageCount = medicineDetails.length; final controller = PageController(); return Padding( padding: EdgeInsets.only(bottom: 3), child: Stack( alignment: Alignment.bottomCenter, children: [ SmoothPageIndicator( controller: controller, // PageController count: pageCount, effect: WormEffect(dotWidth: 7, dotHeight: 7)), PageView( children: List.generate(pageCount, (index) { return GridView.count( physics: const NeverScrollableScrollPhysics(), crossAxisCount: 3, mainAxisSpacing: 20, crossAxisSpacing: 35, padding: EdgeInsets.symmetric( horizontal: 30, ), children: medicineDetails .sublist(index * 6, min((index + 1) * 6, maxPageCount)) .map((e) { return GestureDetector( onTap: () { Navigator.of(context).push(SlidePageRoute( builder: MedicineDetailPage(name: "${e['text']}"), )); }, child: Column( children: [ Expanded( flex: 2, child: null != e['icon'] ? CircleAvatar( backgroundColor: Theme.of(context).secondaryHeaderColor, backgroundImage: Image.network( e['icon'], fit: BoxFit.cover, loadingBuilder: (context, child, loadingProgress) { if (loadingProgress == null) { return child; } else { return Icon(Icons.downloading_outlined); } }, ).image, radius: 50, ) : CircleAvatar( backgroundColor: Theme.of(context).secondaryHeaderColor, )), Expanded( flex: 1, child: Text( '${e['text']}', style: TextStyle( fontSize: 13, fontWeight: FontWeight.w400, color: Colors.black.withAlpha(170)), ), ) ], ), ); }).toList()); }).toList(), controller: controller, ) ], ), ); })) ], ), ), ); } else { return Container( alignment: Alignment.center, child: Text( '- 没有更多了 -', style: TextStyle(color: Colors.grey), ), ); } }); } else { return Center( child: SpinKitFadingCircle( color: Theme.of(context).primaryColor, size: 32, )); } }), ); } }