效果图
前言:
boss直聘APP相信大家都用过吧 这个,个人中心页面布局效果也不难 原生安卓 iOS 实现都比较的简单。
我这里就不展开讲,今天主要讲解flutter版本如何实现 废话不多说我正式开始 。
具体实现
1.头部的appbar的实现
这里我们使用的是 Scaffold 脚手架框架配合SliverAppBar 来实现的 具体代码如下 当让你也可以用其他方式实现 代码如下:
new SliverAppBar(
expandedHeight: _appBarHeight,
flexibleSpace: new FlexibleSpaceBar(
collapseMode: CollapseMode.parallax,
background: new Stack(
fit: StackFit.expand,
children: [
const DecoratedBox(
decoration: const BoxDecoration(
gradient: const LinearGradient(
begin: const Alignment(0.0, -1.0),
end: const Alignment(0.0, -0.4),
colors: const [
const Color(0x00000000),
const Color(0x00000000)
],
),
),
),
new Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
new Expanded(
flex: 3,
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
new Padding(
padding: const EdgeInsets.only(
top: 30.0,
left: 30.0,
bottom: 15.0,
),
child: new Text(
'Rei Ki',
style: new TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 35.0),
),
),
new Padding(
padding: const EdgeInsets.only(
left: 30.0,
),
child: new Text(
'在职-不考虑机会',
style: new TextStyle(
color: Colors.white, fontSize: 15.0),
),
),
],
),
),
new Expanded(
flex: 1,
child: new Padding(
padding: const EdgeInsets.only(
top: 40.0,
right: 30.0,
),
child: new CircleAvatar(
radius: 35.0,
backgroundImage: new NetworkImage(_userHead),
),
),
)
],
),
],
),
),
),
2.下面我们重点讲一下中间 这个横向布局的实现
我们可以直接用Row组件里面嵌套Column 实现 但是代码嵌套多层看起非常臃肿 这是我们自己定义一个组件 因为这个中间的内容基本是重复的 我们自定义一个 ContactItem 来简单的封装一下代码 具体实现
import 'package:flutter/material.dart';
/***
* 创建人:xuqing
* 创建时间:2020年2月5日18:30:50
* 类说明:横向布局的 封装
*/
class ContactItem extends StatelessWidget {
ContactItem({Key key, this.count, this.title, this.onPressed})
: super(key: key);
final String count;
final String title;
final VoidCallback onPressed;
@override
Widget build(BuildContext context) {
return new GestureDetector(
onTap: onPressed,
child: new Column(
children: [
new Padding(
padding: const EdgeInsets.only(
bottom: 4.0,
),
child: new Text(count, style: new TextStyle(fontSize: 18.0)),
),
new Text(title,
style: new TextStyle(color: Colors.black54, fontSize: 14.0)),
],
),
);
}
}
我门封装了 ContactItem 里面写了一个人Column 里面分别线性布局分别包含了纵向排列的Text我们可以统一的设置这两个的Padding 和样式 (color 和fontSize )然后我们在main.dart 里面去调用具体实现的代码如下
new Container(
color: Colors.white,
child: new Padding(
padding: const EdgeInsets.only(
top: 10.0,
bottom: 10.0,
),
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
new ContactItem(
count: '696',
title: '沟通过',
),
new ContactItem(
count: '0',
title: '面试',
),
new ContactItem(
count: '71',
title: '已投递',
),
new ContactItem(
count: '53',
title: '感兴趣',
),
],
),
),
),
3.完成这个还有下面的一部分列表的实现 我们先看效果图
我们看到效果图 每一行基本都是重复的 左边一个icon 和一个title 最右边一个icon
我们这里简单封装一个 menu_item 来实现 具体代码
import 'package:flutter/material.dart';
/**
* 创建人:xuqing
* 创建时间 :2020年2月4日21:39:42
*
*/
class MenuItem extends StatelessWidget {
final IconData icon;
final String title;
final VoidCallback onPressed;
MenuItem({Key key, this.icon, this.title, this.onPressed}) : super(key: key);
@override
Widget build(BuildContext context) {
// TODO: implement build
return new GestureDetector(
onTap: onPressed,
child: new Column(
children: [
new Padding(
padding: EdgeInsets.only(
left: 20.0,
top: 12.0,
right: 20.0,
bottom: 10.0,
),
child: new Row(
children: [
new Padding(padding: const EdgeInsets.only(
right: 8.0,
),
child:new Icon(
icon,
color: Colors.black54,
),
),
new Expanded(
child: new Text(
title,
style: new TextStyle(color: Colors.black54,fontSize: 16.0),
)
),
new Icon(
Icons.chevron_right,
color: Colors.grey,
)
],
)
),
new Padding(padding: const EdgeInsets.only(left: 20.0,right: 20.0),
child: new Divider(
color: Colors.black54,
),
)
],
),
);
}
}
MenuItem 里面我们写一个Column 里面在嵌套一个Row横向的线性布局 ,然后里面我们具体的 写一个左边的Icon 里面的icon属性我们就用构造函数传过来的icon属性, 然后就是一个 title文字的显示同一样我们构造函数传过来的 字符串来替换掉里面的title 属性, 然后就是最右边都是一样的 icon 我们统一设置成 Icons.chevron_right,就可以了, 然后我们在main.dart 里面去调用具体实现的代码如下 :
new Container(
color: Colors.white,
margin: const EdgeInsets.only(top: 10.0),
child: Column(
children: [
new MenuItem(
icon: Icons.face,
title: '体验新版本',
onPressed: (){
print("体验新版本 ---- >");
},
),
new MenuItem(
icon: Icons.print,
title: '我的微简历',
),
new MenuItem(
icon: Icons.archive,
title: '附件简历',
),
new MenuItem(
icon: Icons.home,
title: '管理求职意向',
),
new MenuItem(
icon: Icons.title,
title: '提升简历排名',
),
new MenuItem(
icon: Icons.chat,
title: '牛人问答',
),
new MenuItem(
icon: Icons.assessment,
title: '关注公司',
),
new MenuItem(
icon: Icons.add_shopping_cart,
title: '钱包',
),
new MenuItem(
icon: Icons.security,
title: '隐私设置',
),
],
),
),
最后我们要在最外层嵌套一个 CustomScrollView 防止内容超出屏幕高度导致报错 嵌套CustomScrollView 超出屏幕高度可以滑动
body: new CustomScrollView()
完整的main.dart代码实现如下
import 'package:flutter/material.dart';
import 'menu_item.dart';
import 'contact_item.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.green,
),
home:MyHomePage()
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() {
return _MyHomePageState();
}
}
class _MyHomePageState extends State {
final double _appBarHeight = 180.0;
final String _userHead =
'https://img.bosszhipin.com/beijin/mcs/useravatar/20171211/4d147d8bb3e2a3478e20b50ad614f4d02062e3aec7ce2519b427d24a3f300d68_s.jpg';
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Scaffold(
backgroundColor: new Color.fromARGB(255, 242, 242, 245),
body: new CustomScrollView(
slivers: [
new SliverAppBar(
expandedHeight: _appBarHeight,
flexibleSpace: new FlexibleSpaceBar(
collapseMode: CollapseMode.parallax,
background: new Stack(
fit: StackFit.expand,
children: [
const DecoratedBox(
decoration: const BoxDecoration(
gradient: const LinearGradient(
begin: const Alignment(0.0, -1.0),
end: const Alignment(0.0, -0.4),
colors: const [
const Color(0x00000000),
const Color(0x00000000)
],
),
),
),
new Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
new Expanded(
flex: 3,
child: new Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
new Padding(
padding: const EdgeInsets.only(
top: 30.0,
left: 30.0,
bottom: 15.0,
),
child: new Text(
'Rei Ki',
style: new TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 35.0),
),
),
new Padding(
padding: const EdgeInsets.only(
left: 30.0,
),
child: new Text(
'在职-不考虑机会',
style: new TextStyle(
color: Colors.white, fontSize: 15.0),
),
),
],
),
),
new Expanded(
flex: 1,
child: new Padding(
padding: const EdgeInsets.only(
top: 40.0,
right: 30.0,
),
child: new CircleAvatar(
radius: 35.0,
backgroundImage: new NetworkImage(_userHead),
),
),
)
],
),
],
),
),
),
new SliverList(
delegate: new SliverChildListDelegate(
[
new Container(
color: Colors.white,
child: new Padding(
padding: const EdgeInsets.only(
top: 10.0,
bottom: 10.0,
),
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
new ContactItem(
count: '696',
title: '沟通过',
),
new ContactItem(
count: '0',
title: '面试',
),
new ContactItem(
count: '71',
title: '已投递',
),
new ContactItem(
count: '53',
title: '感兴趣',
),
],
),
),
),
new Container(
color: Colors.white,
margin: const EdgeInsets.only(top: 10.0),
child: Column(
children: [
new MenuItem(
icon: Icons.face,
title: '体验新版本',
onPressed: (){
print("体验新版本 ---- >");
},
),
new MenuItem(
icon: Icons.print,
title: '我的微简历',
),
new MenuItem(
icon: Icons.archive,
title: '附件简历',
),
new MenuItem(
icon: Icons.home,
title: '管理求职意向',
),
new MenuItem(
icon: Icons.title,
title: '提升简历排名',
),
new MenuItem(
icon: Icons.chat,
title: '牛人问答',
),
new MenuItem(
icon: Icons.assessment,
title: '关注公司',
),
new MenuItem(
icon: Icons.add_shopping_cart,
title: '钱包',
),
new MenuItem(
icon: Icons.security,
title: '隐私设置',
),
],
),
),
],
),
)
],
),
);
}
}
最后总结:
我也是学习flutter的新手,这个模仿boss直聘个人中心页面 相对简单 有很多种实现方法 我这边只是提供个人觉得代码嵌套相对的较少的一种, 如果觉得其他更好的实现方法 欢迎留言。具体实现 就是自己定义的 ContactItem 组件和 MenuItem组件,比起安卓原生和iOS 布局和其他逻辑代码完全分开 flutter 的布局代码相对臃肿也是一大槽点所以我们要多用自定义的组件来处理复杂的布局 。文章到此就要结束了 有兴趣的朋友可以留言
项目地址:https://gitee.com/qiuyu123/fluttercopyboss.git