|
@@ -1,3 +1,4 @@
|
|
|
+import 'package:after_layout/after_layout.dart';
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
|
class SelfHomePage extends StatelessWidget {
|
|
@@ -5,17 +6,19 @@ class SelfHomePage extends StatelessWidget {
|
|
|
|
|
|
@override
|
|
|
Widget build(BuildContext context) {
|
|
|
- double rpx=MediaQuery.of(context).size.width/750;
|
|
|
+ double rpx = MediaQuery.of(context).size.width / 750;
|
|
|
return Scaffold(
|
|
|
body: Container(
|
|
|
- child: HomeMain(rpx: rpx,),
|
|
|
+ child: HomeMain(
|
|
|
+ rpx: rpx,
|
|
|
+ ),
|
|
|
),
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
class HomeMain extends StatefulWidget {
|
|
|
- HomeMain({Key key,@required this.rpx}) : super(key: key);
|
|
|
+ HomeMain({Key key, @required this.rpx}) : super(key: key);
|
|
|
final double rpx;
|
|
|
_HomeMainState createState() => _HomeMainState();
|
|
|
}
|
|
@@ -27,10 +30,13 @@ class _HomeMainState extends State<HomeMain> with TickerProviderStateMixin {
|
|
|
double rpx;
|
|
|
AnimationController animationController;
|
|
|
Animation<double> anim;
|
|
|
+ TabController tabController;
|
|
|
+ double expanedHeight=300;
|
|
|
|
|
|
@override
|
|
|
void initState() {
|
|
|
super.initState();
|
|
|
+ tabController=TabController(vsync: this,length: 3);
|
|
|
prev_dy = 0;
|
|
|
fitType = BoxFit.fitWidth;
|
|
|
animationController =
|
|
@@ -43,7 +49,7 @@ class _HomeMainState extends State<HomeMain> with TickerProviderStateMixin {
|
|
|
prev_dy = changed;
|
|
|
}
|
|
|
extraPicHeight += changed - prev_dy;
|
|
|
- if (extraPicHeight >= 200*widget.rpx) {
|
|
|
+ if (extraPicHeight >= 200 * widget.rpx) {
|
|
|
fitType = BoxFit.fitHeight;
|
|
|
} else {
|
|
|
fitType = BoxFit.fitWidth;
|
|
@@ -51,7 +57,13 @@ class _HomeMainState extends State<HomeMain> with TickerProviderStateMixin {
|
|
|
setState(() {
|
|
|
prev_dy = changed;
|
|
|
extraPicHeight = extraPicHeight;
|
|
|
- fitType=fitType;
|
|
|
+ fitType = fitType;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ updateExpandedHeight(height){
|
|
|
+ setState(() {
|
|
|
+ expanedHeight=height;
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -59,14 +71,14 @@ class _HomeMainState extends State<HomeMain> with TickerProviderStateMixin {
|
|
|
setState(() {
|
|
|
anim = Tween(begin: extraPicHeight, end: 0.0).animate(animationController)
|
|
|
..addListener(() {
|
|
|
- if (extraPicHeight >= widget.rpx*200) {
|
|
|
+ if (extraPicHeight >= widget.rpx * 200) {
|
|
|
fitType = BoxFit.fitHeight;
|
|
|
} else {
|
|
|
fitType = BoxFit.fitWidth;
|
|
|
}
|
|
|
setState(() {
|
|
|
extraPicHeight = anim.value;
|
|
|
- fitType=fitType;
|
|
|
+ fitType = fitType;
|
|
|
});
|
|
|
});
|
|
|
prev_dy = 0;
|
|
@@ -104,12 +116,19 @@ class _HomeMainState extends State<HomeMain> with TickerProviderStateMixin {
|
|
|
icon: Icon(Icons.arrow_back),
|
|
|
onPressed: () {},
|
|
|
),
|
|
|
- expandedHeight: 510 * rpx + extraPicHeight,
|
|
|
- flexibleSpace: FlexibleSpaceBar(
|
|
|
- // title: Text("Flutter SliverAppBar"),
|
|
|
- background: SliverTopBar(
|
|
|
+ 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,
|
|
|
),
|
|
|
),
|
|
|
),
|
|
@@ -117,7 +136,11 @@ class _HomeMainState extends State<HomeMain> with TickerProviderStateMixin {
|
|
|
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),
|
|
|
)
|
|
@@ -126,6 +149,30 @@ class _HomeMainState extends State<HomeMain> with TickerProviderStateMixin {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+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) {
|
|
|
+ RenderBox 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})
|
|
@@ -138,6 +185,7 @@ class SliverTopBar extends StatelessWidget {
|
|
|
return Stack(
|
|
|
children: <Widget>[
|
|
|
Column(
|
|
|
+ mainAxisSize: MainAxisSize.min,
|
|
|
children: <Widget>[
|
|
|
Image.asset(
|
|
|
"lib/images/temple.jpg",
|
|
@@ -146,8 +194,102 @@ class SliverTopBar extends StatelessWidget {
|
|
|
fit: fitType,
|
|
|
),
|
|
|
Container(
|
|
|
+ padding: EdgeInsets.only(top: 20 * rpx),
|
|
|
+ height: 120 * rpx,
|
|
|
+ child: Row(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.end,
|
|
|
+ children: <Widget>[
|
|
|
+ Container(
|
|
|
+ height: 80 * rpx,
|
|
|
+ width: 330 * rpx,
|
|
|
+ child: RaisedButton(
|
|
|
+ color: 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: <Widget>[
|
|
|
+ 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: <Widget>[
|
|
|
+ Row(
|
|
|
+ children: <Widget>[
|
|
|
+ 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(
|
|
@@ -155,16 +297,41 @@ class SliverTopBar extends StatelessWidget {
|
|
|
),
|
|
|
),
|
|
|
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: <Widget>[
|
|
|
+ Tag(text:"深圳" ,),
|
|
|
+ Tag(text: "世界之窗",),
|
|
|
+ Tag(text: "深圳大学",)
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Container(padding: EdgeInsets.symmetric(horizontal: 20*rpx,vertical: 30*rpx),child: Row(children: <Widget>[
|
|
|
+ NumWithDesc(numm: "100.2w",desc: "获赞",),
|
|
|
+ NumWithDesc(numm: "15",desc: "关注",),
|
|
|
+ NumWithDesc(numm: "10.8w",desc: "粉丝",),
|
|
|
+ ],),)
|
|
|
],
|
|
|
),
|
|
|
Positioned(
|
|
|
- top: 240 * rpx + extraPicHeight,
|
|
|
+ top: 250 * rpx + extraPicHeight,
|
|
|
left: 30 * rpx,
|
|
|
child: Container(
|
|
|
- width: 180 * rpx,
|
|
|
- height: 180 * rpx,
|
|
|
+ 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"))),
|
|
@@ -173,3 +340,77 @@ class SliverTopBar extends StatelessWidget {
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+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: <Widget>[
|
|
|
+ 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("lib/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,);
|
|
|
+// },))
|
|
|
+// ],
|
|
|
+// ),
|
|
|
+// );
|
|
|
+// }
|
|
|
+// }
|