UI效果
2、注意点:
flutter中的 Text 默认是不支持换行的,而且本身属性的 maxLines 规定了最大行数,但是设置了也不会自动换行。需要借助 Expanded 控件。且 Expanded 的使用方式需要在 包裹 Column,而不是让 Column包裹,否则换行失效(具体说不清楚,可以看实现代码中的 index-news.dart 文件中的写法)。
3、实现代码
1、index-page.dart 文件内容
import 'package:flutter/material.dart';
import 'package:flutter_hook_up_rent/pages/components/index/index-news.dart';
import 'package:flutter_hook_up_rent/pages/components/index/index-recommend.dart';
import '../components/index/common-swiper.dart';
import '../components/index/index-navigator.dart';
class IndexPage extends StatefulWidget {
final String title;
IndexPage({this.title});
@override
_IndexPageState createState() => _IndexPageState();
}
class _IndexPageState extends State<IndexPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xf5f5f5ff),
appBar: AppBar(
title: Text(widget.title),
centerTitle: true,
),
body: ListView(
children: [
CommonSwiper(),
IndexNavigator(),
IndexRecommend(),
IndexNews()
],
));
}
}
2、index-navigator.dart 文件内容
import 'package:flutter/material.dart';
class IndexNavigator extends StatefulWidget {
@override
_IndexNavigatorState createState() => _IndexNavigatorState();
}
class _IndexNavigatorState extends State<IndexNavigator> {
_navigatorOnTap(index) {
print(index);
}
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 10),
width: double.infinity,
child: Row(
children: [
Expanded(
flex: 1,
child: InkWell(
onTap: () {
_navigatorOnTap(1);
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(
Icons.home,
size: 40,
color: Theme.of(context).primaryColor,
),
Text(
"整租",
style: TextStyle(fontSize: 18),
),
],
),
)),
Expanded(
flex: 1,
child: InkWell(
onTap: () {
_navigatorOnTap(2);
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(
Icons.person_add_rounded,
size: 40,
color: Theme.of(context).primaryColor,
),
Text(
"合租",
style: TextStyle(fontSize: 18),
),
],
),
)),
Expanded(
flex: 1,
child: InkWell(
onTap: () {
_navigatorOnTap(3);
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(
Icons.map,
size: 40,
color: Theme.of(context).primaryColor,
),
Text(
"地图找房",
style: TextStyle(fontSize: 18),
),
],
),
)),
Expanded(
flex: 1,
child: InkWell(
onTap: () {
_navigatorOnTap(1);
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(
Icons.recent_actors,
size: 40,
color: Theme.of(context).primaryColor,
),
Text(
"去出租",
style: TextStyle(fontSize: 18),
),
],
),
)),
],
),
);
}
}
3、index-recommend.dart文件内容
import 'package:flutter/material.dart';
class IndexRecommend extends StatefulWidget {
@override
_IndexRecommendState createState() => _IndexRecommendState();
}
class _IndexRecommendState extends State<IndexRecommend> {
List<IndexRecommendItem> dataList = [
IndexRecommendItem(
title: "家住回龙观",
subTitle: "归属的感觉",
imageUrl:
"http://img3.jc001.cn/img/659/1506659/1410/14543881ae88b3f_s.jpg",
navigatorUrl: ""),
IndexRecommendItem(
title: "宜居四五环",
subTitle: "大都市生活",
imageUrl:
"http://img3.jc001.cn/img/659/1506659/1410/14543881ae88b3f_s.jpg",
navigatorUrl: ""),
IndexRecommendItem(
title: "喧嚣三里屯",
subTitle: "繁华的背后",
imageUrl:
"http://img3.jc001.cn/img/659/1506659/1410/14543881ae88b3f_s.jpg",
navigatorUrl: ""),
IndexRecommendItem(
title: "比邻十号线",
subTitle: "地铁心连心",
imageUrl:
"http://img3.jc001.cn/img/659/1506659/1410/14543881ae88b3f_s.jpg",
navigatorUrl: ""),
];
@override
Widget build(BuildContext context) {
return Column(
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 12),
height: 50,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"房屋推荐",
style: TextStyle(color: Colors.black, fontSize: 18),
),
Text("更多 ")
],
),
),
Wrap(
spacing: 10,
runSpacing: 10,
children: dataList
.map((item) => Container(
height: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: Color(0xffffffff)),
width: (MediaQuery.of(context).size.width - 30) / 2,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
item.title,
style:
TextStyle(color: Colors.black, fontSize: 16),
),
Padding(padding: EdgeInsets.all(4)),
Text(
item.subTitle,
style:
TextStyle(color: Colors.black, fontSize: 16),
)
],
),
// Image.network(item.imageUrl)
ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Image(image: NetworkImage(item.imageUrl)),
)
],
),
))
.toList(),
)
],
);
}
}
class IndexRecommendItem {
final String title;
final String subTitle;
final String imageUrl;
final String navigatorUrl;
const IndexRecommendItem(
{this.title, this.subTitle, this.imageUrl, this.navigatorUrl});
}
4、index-news.dart文件内容
import 'package:flutter/material.dart';
class IndexNews extends StatefulWidget {
@override
_IndexNewsState createState() => _IndexNewsState();
}
class _IndexNewsState extends State<IndexNews> {
List dataList = [
InfoItem(
title:
'置业选择 | 安贞西里 三室一厅 河间的古雅别院置业选择 | 安贞西里 三室一厅 河间的古雅别院置业选择 | 安贞西里 三室一厅 河间的古雅别院',
imageUrl:
'https://pic1.ajkimg.com/display/anjuke/93a4d6ef27858b8b1e41c77c1049ca50/240x180c.jpg?t=1&srotate=1',
source: '新华网',
time: '两天前',
navigatorUrl: 'login'),
InfoItem(
title: '置业选择 | 安贞西里 三室一厅 河间的古雅别院',
imageUrl:
'https://pic1.ajkimg.com/display/anjuke/93a4d6ef27858b8b1e41c77c1049ca50/240x180c.jpg?t=1&srotate=1',
source: '新华网',
time: '两天前',
navigatorUrl: 'login'),
InfoItem(
title: '置业选择 | 安贞西里 三室一厅 河间的古雅别院',
imageUrl:
'https://pic1.ajkimg.com/display/anjuke/93a4d6ef27858b8b1e41c77c1049ca50/240x180c.jpg?t=1&srotate=1',
source: '新华网',
time: '两天前',
navigatorUrl: 'login'),
InfoItem(
title: '置业选择 | 安贞西里 三室一厅 河间的古雅别院',
imageUrl:
'https://pic1.ajkimg.com/display/anjuke/93a4d6ef27858b8b1e41c77c1049ca50/240x180c.jpg?t=1&srotate=1',
source: '新华网',
time: '两天前',
navigatorUrl: 'login'),
InfoItem(
title: '置业选择 | 安贞西里 三室一厅 河间的古雅别院',
imageUrl:
'https://pic1.ajkimg.com/display/anjuke/93a4d6ef27858b8b1e41c77c1049ca50/240x180c.jpg?t=1&srotate=1',
source: '新华网',
time: '两天前',
navigatorUrl: 'login'),
InfoItem(
title: '置业选择 | 安贞西里 三室一厅 河间的古雅别院',
imageUrl:
'https://pic1.ajkimg.com/display/anjuke/93a4d6ef27858b8b1e41c77c1049ca50/240x180c.jpg?t=1&srotate=1',
source: '新华网',
time: '两天前',
navigatorUrl: 'login'),
InfoItem(
title: '置业选择 | 安贞西里 三室一厅 河间的古雅别院',
imageUrl:
'https://pic1.ajkimg.com/display/anjuke/93a4d6ef27858b8b1e41c77c1049ca50/240x180c.jpg?t=1&srotate=1',
source: '新华网',
time: '两天前',
navigatorUrl: 'login'),
InfoItem(
title: '置业选择 | 安贞西里 三室一厅 河间的古雅别院',
imageUrl:
'https://pic1.ajkimg.com/display/anjuke/93a4d6ef27858b8b1e41c77c1049ca50/240x180c.jpg?t=1&srotate=1',
source: '新华网',
time: '两天前',
navigatorUrl: 'login'),
InfoItem(
title: '置业选择 | 安贞西里 三室一厅 河间的古雅别院',
imageUrl:
'https://pic1.ajkimg.com/display/anjuke/93a4d6ef27858b8b1e41c77c1049ca50/240x180c.jpg?t=1&srotate=1',
source: '新华网',
time: '两天前',
navigatorUrl: 'login'),
InfoItem(
title: '置业选择 | 安贞西里 三室一厅 河间的古雅别院',
imageUrl:
'https://pic1.ajkimg.com/display/anjuke/93a4d6ef27858b8b1e41c77c1049ca50/240x180c.jpg?t=1&srotate=1',
source: '新华网',
time: '两天前',
navigatorUrl: 'login')
];
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 0, bottom: 20, left: 12, right: 12),
child: Column(
children: [
Container(
height: 50,
width: double.infinity,
child: Row(
children: [
Text(
"最新资讯",
style: TextStyle(color: Colors.black, fontSize: 18),
),
Text("")
],
),
),
...dataList
.map((item) => Container(
margin: EdgeInsets.only(bottom: 10),
width: double.infinity,
height: 120,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: Color(0xffffffff),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(padding: EdgeInsets.all(5)),
Image(height: 100, image: NetworkImage(item.imageUrl)),
Container(
child: Expanded(
child: Container(
padding: EdgeInsets.all(10),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(item.title,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 18)),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(item.source,
style: TextStyle(
fontSize: 14,
color: Colors.grey[400])),
Text(item.time,
style: TextStyle(
fontSize: 14,
color: Colors.grey[400]))
],
)
],
),
)),
)
],
),
))
.toList(),
],
),
);
}
}
class InfoItem {
final String title;
final String imageUrl;
final String source;
final String time;
final String navigatorUrl;
InfoItem(
{this.title, this.imageUrl, this.source, this.time, this.navigatorUrl});
}