#yyds干货盘点#flutter示例_ico

import 'dart:math';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'dart:ui';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(MaterialApp(home: DunDunView()));

class DunDunView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverPersistentHeader(
pinned: true,
delegate: SliverCustomHeaderDelegate(
title: '哪吒之魔童降世',
collapsedHeight: 40,
expandedHeight: 300,
paddingTop: MediaQuery.of(context).padding.top,
coverImgUrl:
'https://img.win3000.com/m00/5f/a2/7b873c0d139ea7e142f6843a300a793a.jpg'),
),
SliverFillRemaining(
child: FilmContent(),
)
],
),
);
}
}

class SliverCustomHeaderDelegate extends SliverPersistentHeaderDelegate {
final double collapsedHeight;
final double expandedHeight;
final double paddingTop;
final String coverImgUrl;
final String title;
String statusBarMode = 'dark';

SliverCustomHeaderDelegate({
required this.collapsedHeight,
required this.expandedHeight,
required this.paddingTop,
required this.coverImgUrl,
required this.title,
});

@override
double get minExtent => this.collapsedHeight + this.paddingTop;

@override
double get maxExtent => this.expandedHeight;

@override
bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
return true;
}

void updateStatusBarBrightness(shrinkOffset) {
if (shrinkOffset > 50 && this.statusBarMode == 'dark') {
this.statusBarMode = 'light';
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarBrightness: Brightness.light,
statusBarIconBrightness: Brightness.light,
));
} else if (shrinkOffset <= 50 && this.statusBarMode == 'light') {
this.statusBarMode = 'dark';
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarBrightness: Brightness.dark,
statusBarIconBrightness: Brightness.dark,
));
}
}

Color makeStickyHeaderBgColor(shrinkOffset) {
final int alpha = (shrinkOffset / (this.maxExtent - this.minExtent) * 255)
.clamp(0, 255)
.toInt();
return Color.fromARGB(alpha, 255, 255, 255);
}

Color makeStickyHeaderTextColor(shrinkOffset, isIcon) {
if (shrinkOffset <= 50) {
return isIcon ? Colors.white : Colors.transparent;
} else {
final int alpha = (shrinkOffset / (this.maxExtent - this.minExtent) * 255)
.clamp(0, 255)
.toInt();
return Color.fromARGB(alpha, 0, 0, 0);
}
}

@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
this.updateStatusBarBrightness(shrinkOffset);
return Container(
height: this.maxExtent,
width: MediaQuery.of(context).size.width,
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Container(child: Image.network(this.coverImgUrl, fit: BoxFit.cover)),
Positioned(
left: 0,
top: this.maxExtent / 2,
right: 0,
bottom: 0,
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color(0x00000000),
Color(0x90000000),
],
),
),
),
),
Positioned(
left: 0,
right: 0,
top: 0,
child: Container(
color: this.makeStickyHeaderBgColor(shrinkOffset),
child: SafeArea(
bottom: false,
child: Container(
height: this.collapsedHeight,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
IconButton(
icon: Icon(
Icons.arrow_back_ios,
color: this
.makeStickyHeaderTextColor(shrinkOffset, true),
),
onPressed: () => Navigator.pop(context),
),
Text(
this.title,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w500,
color: this
.makeStickyHeaderTextColor(shrinkOffset, false),
),
),
IconButton(
icon: Icon(
Icons.share,
color: this
.makeStickyHeaderTextColor(shrinkOffset, true),
),
onPressed: () {},
),
],
),
),
),
),
),
],
),
);
}
}

class FilmContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(padding: EdgeInsets.only(left: 16)),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'铁道英雄',
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: Color(0xFF333333),
),
),
Padding(padding: EdgeInsets.only(top: 10)),
Text(
'战争/中国大陆/110分钟',
style: TextStyle(
fontSize: 15,
color: Color(0xFF999999),
),
),
Padding(padding: EdgeInsets.only(top: 2)),
Text(
'2021年中国大陆上映',
style: TextStyle(
fontSize: 15,
color: Color(0xFF999999),
),
),
Padding(padding: EdgeInsets.only(top: 2)),
Text(
'32.1万人想看/大V推荐度95%',
style: TextStyle(
fontSize: 15,
color: Color(0xFF999999),
),
),
],
),
],
),
Divider(height: 32),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'剧情简介',
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: Color(0xFF333333),
),
),
Padding(padding: EdgeInsets.only(top: 10)),
Text(
'抗日战争时期,在日军肆虐横行的鲁南地区,临城枣庄英勇的“铁道队”穿铁轨、扒火车,截取武器和物资,用胆识和智慧与敌人斗争到底,殊死捍卫家园,为抗战胜利作出突出贡献。  本片是根据发生在1935年-1945年间,洪振海、王志胜、杜季伟、刘金山等“铁道队”队员的真实事迹改编,将最大限度地还原“铁道队”的英雄故事',
textAlign: TextAlign.justify,
style: TextStyle(
fontSize: 15,
color: Color(0xFF999999),
),
),
],
),
],
),
);
}
}