123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467 |
- import 'package:after_layout/after_layout.dart';
- import 'package:flutter/material.dart';
- class HomePage extends StatelessWidget {
- const HomePage({Key? key}) : super(key: key);
- @override
- Widget build(BuildContext context) {
- double rpx = MediaQuery.of(context).size.width / 750;
- return Scaffold(
- body: Container(
- child: HomeMain(
- rpx: rpx,
- ),
- ),
- );
- }
- }
- class HomeMain extends StatefulWidget {
- HomeMain({Key? key, required this.rpx}) : super(key: key);
- final double rpx;
- _HomeMainState createState() => _HomeMainState();
- }
- class _HomeMainState extends State<HomeMain> with TickerProviderStateMixin {
- double extraPicHeight = 0;
- late BoxFit fitType;
- double prevDy = 0;
- double rpx = 0;
- late AnimationController animationController;
- late Animation<double> anim;
- late TabController tabController;
- double expanedHeight = 300;
- @override
- void initState() {
- super.initState();
- tabController = TabController(vsync: this, length: 3);
- prevDy = 0;
- fitType = BoxFit.fitWidth;
- animationController =
- AnimationController(vsync: this, duration: Duration(milliseconds: 300));
- anim = Tween(begin: 0.0, end: 0.0).animate(animationController);
- }
- updatePicHeight(changed) {
- if (prevDy == 0) {
- prevDy = changed;
- }
- extraPicHeight += changed - prevDy;
- if (extraPicHeight >= 200 * widget.rpx) {
- fitType = BoxFit.fitHeight;
- } else {
- fitType = BoxFit.fitWidth;
- }
- setState(() {
- prevDy = changed;
- extraPicHeight = extraPicHeight;
- fitType = fitType;
- });
- }
- updateExpandedHeight(height) {
- setState(() {
- expanedHeight = height;
- });
- }
- runAnimate() {
- setState(() {
- anim = Tween(begin: extraPicHeight, end: 0.0).animate(animationController)
- ..addListener(() {
- if (extraPicHeight >= widget.rpx * 200) {
- fitType = BoxFit.fitHeight;
- } else {
- fitType = BoxFit.fitWidth;
- }
- setState(() {
- extraPicHeight = anim.value;
- fitType = fitType;
- });
- });
- prevDy = 0;
- });
- }
- @override
- Widget build(BuildContext context) {
- double rpx = MediaQuery.of(context).size.width / 750;
- return Listener(
- onPointerMove: (result) {
- updatePicHeight(result.position.dy);
- },
- onPointerUp: (_) {
- runAnimate();
- animationController.forward(from: 0);
- },
- child: CustomScrollView(
- physics: ClampingScrollPhysics(),
- slivers: <Widget>[
- SliverAppBar(
- pinned: true,
- floating: true,
- actions: <Widget>[
- IconButton(
- icon: Icon(Icons.search),
- onPressed: () {},
- ),
- IconButton(
- icon: Icon(Icons.more_vert),
- onPressed: () {},
- ),
- ],
- leading: IconButton(
- icon: Icon(Icons.arrow_back),
- onPressed: () {},
- ),
- bottom: PreferredSize(
- preferredSize: Size.fromHeight(50),
- child: TabBar(
- controller: tabController,
- tabs: <Widget>[
- Text("作品 91"),
- Text("动态 91"),
- Text("喜欢 91"),
- ],
- )),
- // expandedHeight: 510 * rpx + extraPicHeight,
- expandedHeight: expanedHeight + extraPicHeight,
- flexibleSpace: Container(
- child: TopBarWithCallback(
- extraPicHeight: extraPicHeight,
- fitType: fitType,
- updateHeight: updateExpandedHeight,
- ),
- ),
- ),
- SliverList(
- delegate: SliverChildBuilderDelegate((context, index) {
- return Container(
- height: 30,
- alignment: Alignment.centerLeft,
- color: Colors.blueAccent,
- child: Text("This is itm $index"),
- margin: EdgeInsets.symmetric(
- horizontal: 20 * rpx, vertical: 10 * rpx),
- );
- }, childCount: 80),
- )
- ],
- ));
- }
- }
- class TopBarWithCallback extends StatefulWidget {
- TopBarWithCallback(
- {Key? key,
- required this.extraPicHeight,
- required this.fitType,
- required this.updateHeight})
- : super(key: key);
- final double extraPicHeight;
- final BoxFit fitType;
- final Function(double) updateHeight;
- _TopBarWithCallbackState createState() => _TopBarWithCallbackState();
- }
- class _TopBarWithCallbackState extends State<TopBarWithCallback>
- with AfterLayoutMixin {
- @override
- Widget build(BuildContext context) {
- return Container(
- child: SliverTopBar(
- extraPicHeight: widget.extraPicHeight,
- fitType: widget.fitType,
- ),
- );
- }
- @override
- void afterFirstLayout(BuildContext context) {
- RenderObject? box = context.findRenderObject();
- // double height =
- // box.getMaxIntrinsicHeight(MediaQuery.of(context).size.width);
- // widget.updateHeight(height);
- }
- }
- class SliverTopBar extends StatelessWidget {
- const SliverTopBar(
- {Key? key, required this.extraPicHeight, required this.fitType})
- : super(key: key);
- final double extraPicHeight;
- final BoxFit fitType;
- @override
- Widget build(BuildContext context) {
- double rpx = MediaQuery.of(context).size.width / 750;
- return Stack(
- children: [
- Column(
- mainAxisSize: MainAxisSize.min,
- children: [
- Image.asset(
- "assets/images/temple.jpg",
- width: 750 * rpx,
- height: 300 * rpx + extraPicHeight,
- fit: fitType,
- ),
- Container(
- padding: EdgeInsets.only(top: 20 * rpx),
- height: 120 * rpx,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.end,
- children: [
- Container(
- height: 80 * rpx,
- width: 330 * rpx,
- child: ElevatedButton(
- style: ButtonStyle(
- foregroundColor: MaterialStateProperty.all(Color(0xffdc3254))
- ),
- child: Text(
- "+关注",
- style: TextStyle(
- fontSize: 30 * rpx,
- color: Colors.white,
- letterSpacing: 3 * rpx),
- ),
- onPressed: () {},
- )),
- SizedBox(
- width: 10 * rpx,
- ),
- Container(
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(2),
- color: Color(0xff3b3c49),
- ),
- height: 80 * rpx,
- child: IconButton(
- icon: Center(
- child: Icon(
- Icons.arrow_drop_down,
- color: Colors.white,
- size: 50 * rpx,
- )),
- onPressed: () {},
- ),
- ),
- SizedBox(
- width: 30 * rpx,
- )
- ],
- ),
- ),
- SizedBox(
- height: 100 * rpx,
- ),
- Container(
- width: 750 * rpx,
- padding: EdgeInsets.symmetric(horizontal: 30 * rpx),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- "马友发",
- style: TextStyle(
- fontSize: 55 * rpx,
- color: Colors.white,
- fontWeight: FontWeight.bold),
- ),
- Text("抖音号:1234567",
- style: TextStyle(
- fontSize: 27 * rpx,
- color: Colors.white,
- )),
- SizedBox(
- height: 15 * rpx,
- )
- ],
- )),
- Padding(
- padding: EdgeInsets.symmetric(horizontal: 20 * rpx),
- child: Divider(
- color: Colors.grey[700],
- ),
- ),
- Container(
- padding: EdgeInsets.symmetric(horizontal: 20 * rpx),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Row(
- children: [
- Icon(
- Icons.shop,
- color: Color(0xffeacd3f),
- ),
- Text(
- "商品橱窗",
- style: TextStyle(color: Color(0xffeacd3f)),
- )
- ],
- ),
- Icon(Icons.keyboard_arrow_right, color: Color(0xffeacd3f))
- ],
- )),
- Padding(
- padding: EdgeInsets.symmetric(horizontal: 20 * rpx),
- child: Divider(
- color: Colors.grey[700],
- ),
- ),
- Container(
- padding: EdgeInsets.symmetric(horizontal: 20 * rpx),
- height: 100 * rpx,
- width: 750 * rpx,
- child: Text(
- "爱神的箭发;黑色大力开发哈的\n阿萨德饭还是电话费拉开始的计划发",
- style: TextStyle(color: Colors.white, fontSize: 30 * rpx),
- ),
- ),
- Container(
- padding: EdgeInsets.symmetric(
- horizontal: 20 * rpx, vertical: 10 * rpx),
- child: Row(
- children: [
- Tag(
- text: "深圳",
- ),
- Tag(
- text: "世界之窗",
- ),
- Tag(
- text: "深圳大学",
- )
- ],
- ),
- ),
- Container(
- padding: EdgeInsets.symmetric(
- horizontal: 20 * rpx, vertical: 30 * rpx),
- child: Row(
- children: [
- NumWithDesc(
- numm: "100.2w",
- desc: "获赞",
- ),
- NumWithDesc(
- numm: "15",
- desc: "关注",
- ),
- NumWithDesc(
- numm: "10.8w",
- desc: "粉丝",
- ),
- ],
- ),
- )
- ],
- ),
- Positioned(
- top: 250 * rpx + extraPicHeight,
- left: 30 * rpx,
- child: Container(
- decoration: BoxDecoration(
- color: Theme.of(context).primaryColor,
- borderRadius: BorderRadius.circular(220 * rpx)),
- width: 220 * rpx,
- height: 220 * rpx,
- padding: EdgeInsets.all(10 * rpx),
- child: CircleAvatar(
- backgroundImage: NetworkImage(
- "https://pic2.zhimg.com/v2-a88cd7618933272ca681f86398e6240d_xll.jpg"))),
- )
- ],
- );
- }
- }
- class Tag extends StatelessWidget {
- const Tag({Key? key, required this.text}) : super(key: key);
- final String text;
- @override
- Widget build(BuildContext context) {
- double rpx = MediaQuery.of(context).size.width / 750;
- return Container(
- child: Text(
- text,
- style: TextStyle(fontSize: 26 * rpx, color: Color(0xff64626e)),
- ),
- color: Color(0xff3b3c49),
- padding: EdgeInsets.all(10 * rpx),
- margin: EdgeInsets.only(right: 10 * rpx),
- );
- }
- }
- class NumWithDesc extends StatelessWidget {
- const NumWithDesc({Key? key, required this.numm, required this.desc})
- : super(key: key);
- final String numm;
- final String desc;
- @override
- Widget build(BuildContext context) {
- double rpx = MediaQuery.of(context).size.width / 750;
- double textSize = 35 * rpx;
- return Padding(
- padding: EdgeInsets.only(right: 20 * rpx),
- child: Row(
- children: [
- Text(
- numm,
- style: TextStyle(
- fontSize: textSize,
- color: Colors.white,
- fontWeight: FontWeight.bold),
- ),
- SizedBox(
- width: 10 * rpx,
- ),
- Text(desc,
- style: TextStyle(fontSize: textSize, color: Color(0xff3b3c49)))
- ],
- ));
- }
- }
- // import 'package:flutter/material.dart';
- // class SelfHomePage extends StatelessWidget {
- // const SelfHomePage({Key? key}) : super(key: key);
- // @override
- // Widget build(BuildContext context) {
- // return Scaffold(
- // body: CustomScrollView(
- // physics: ClampingScrollPhysics(),
- // slivers: <Widget>[
- // SliverAppBar(
- // leading: IconButton(
- // icon: Icon(Icons.arrow_back),
- // onPressed: () {},
- // ),
- // floating: true,
- // pinned: false,
- // snap: true,
- // expandedHeight: 250,
- // flexibleSpace: FlexibleSpaceBar(
- // title: Text("This is Sliver App Bar"),
- // background: Image.asset("assets/images/temple.jpg",height: 250,fit: BoxFit.fitWidth,),
- // ),
- // ),
- // SliverList(delegate: SliverChildBuilderDelegate((context,index){
- // return Container(child: Text("This is item $index",style: TextStyle(fontSize: 20),),color: Colors.redAccent,);
- // },))
- // ],
- // ),
- // );
- // }
- // }
|