This article is mainly written about the gold nuggets APP boiling point page, the effect is as follows:
To add a Tabbar first
I wrote about Tabbar in a previous article. So you can just use it. portal
Boiling point page header content build
This part of the content is similar to the home page, can be encapsulated into a component, pass the data in, and then apply it. So far it looks like this:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class SearchTop extends StatefulWidget {
SearchTop({Key key}) : super(key: key);
@override
_SearchTopState createState() => _SearchTopState();
}
class _SearchTopState extends State<SearchTop> {
String currentString = 'recommendations';
tagButton({title = 'recommendations'{})return FlatButton(
onPressed: () {
setState(() {
currentString = title;
});
},
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.symmetric(vertical: 5),
child: Text(title,
style: currentString == title
? TextStyle(fontSize: 20, color: Colors.blue)
: TextStyle(fontSize: 18, color: Colors.grey)), ), Offstage( offstage: currentString ! = title, child: Container( height:2,
width: title.length.toDouble() * 20,
decoration: BoxDecoration(color: Colors.blue),
),
)
],
));
}
renderTag() {
return Container(
width: Get.width,
decoration: BoxDecoration(color: Colors.white),
padding: EdgeInsets.only(
top: Get.context.mediaQueryPadding.top, left: 10, right: 10),
child: Row(
children: [
Expanded(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
'recommendations'.'hot'.'attention'.'front end'.'Fishing at work'.'Push recruitment'.'A hole in the tree'.'Learned today'.'A picture is worth a thousand words'.'Algorithm of the Day',
].map<Widget>((e) => tagButton(title: e)).toList(),
),
)),
InkWell(
onTap: () {},
child: Container(
padding: EdgeInsets.only(left: 10),
child: Icon(
Icons.list_alt,
color: Colors.grey,
size: 24() [() [() [(). }@override
Widget build(BuildContext context) {
returnrenderTag(); }}Copy the code
The second half of the list is built
First analyze a wave of pages, divided into two parts, the top part is a horizontal scroll list, the bottom part is a boiling point content list, image type, text type, link type
Horizontal scrolling list building
Make the first item returned in the list a horizontal scroll view and create a new search_hot.dart file
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class SearchHot extends StatefulWidget {
SearchHot({Key key}) : super(key: key);
@override
_SearchHotState createState() => _SearchHotState();
}
class _SearchHotState extends State<SearchHot> {
@override
Widget build(BuildContext context) {
return Container(
height: 100,
width: Get.width - 20,
margin: EdgeInsets.only(top: 10, left: 10),
padding: EdgeInsets.symmetric(horizontal: 20),
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(5)),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'🔥 there's a new tool, check it out check it out check it out ',
style: TextStyle(fontSize: 18),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
Padding(
padding: EdgeInsets.only(top: 5),
child: Text(
'Like 89· Reading 123· One Morning',
style: TextStyle(fontSize: 14, color: Colors.grey),
),
)
],
)),
Offstage(
offstage: false,
child: Container(
height: 60,
width: 60, decoration: BoxDecoration(color: Colors.red), ), ) ], ), ); }}Copy the code
Use it on the page
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
SearchTop(),
Expanded(
child: CommonListWiget(
networkApi: (currentPage) async {
Future.delayed(Duration(milliseconds: 500)).then((value) => {
dataList.addAll(['1'.'2'])});return dataList;
},
itemBuilder: (BuildContext context, int position) {
if (position == 0) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
SearchHot(),
SearchHot(),
SearchHot(),
],
),
);
}
return ListTile(
title: Text('test' + position.toString()),
subtitle: Text('Some description')); })),])); }Copy the code
Bottom list building
Dart file search_item.dart file search_item.dart file search_item.dart
Boiling point information
renderAvatar() {
return Row(
children: [
ClipOval(
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(color: Colors.red),
),
),
Container(
margin: EdgeInsets.symmetric(horizontal: 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'the tree hole robot',
style: TextStyle(fontSize: 16, color: Colors.black),
),
Text(
'Automatic Anonymous robot @ # Tree hole #·31 minutes ago',
style: TextStyle(fontSize: 14, color: Colors.grey),
),
],
),
)
],
);
}
@override
Widget build(BuildContext context) {
return Container(
width: Get.width,
decoration: BoxDecoration(color: Colors.white),
padding: EdgeInsets.all(15),
margin: EdgeInsets.only(top: 10),
child: Column(
children: [
renderAvatar(),
],
),
);
}
Copy the code
The next step is to distinguish between displaying text and images based on type
Display of different states
Display text, which contains functions, after the number of lines is more than 3, display the expand button, click to expand.
//TQExpandableText is a packaged tool widget
renderType() {
if (widget.type == 1) {
// Display text
return Container(
margin: EdgeInsets.symmetric(horizontal: 10, vertical: 10),
child: TQExpandableText(
'there is a new tool, hurriedly see seem to see have a new tool, hurriedly to see seems to see how the new tool, hurriedly to see seems to see how the new tool, hurriedly to see seems to see how the new tool, hurriedly to see seems to see how the new tools, hurriedly to see seems to see how the new tools, hurriedly to see seems to see how the new tools, hurriedly run seems to see',
expandText: 'full',
collapseText: 'put',
maxLines: 3,
style: TextStyle(fontSize: 14, color: Colors.black.withOpacity(0.8)))); }else if (widget.type == 2) {
// Display text plus images
} else if (widget.type == 3) {
// Display text plus images
}
return Container();
}
Copy the code
Show the picture, click on the picture to enlarge the effect, mainly using Hero animation to complete
Main code (PS: the picture is in the digging gold boiling point to find a network picture 😄)
// Display text plus images
return Hero(
tag: 'imgaesView',
child: Material(
child: InkWell(
onTap: () {
Navigator.push(
context,
new PageRouteBuilder(
transitionDuration: const Duration(milliseconds: 250),
pageBuilder: (context, _, __) => Scaffold(
body: InkWell(
onTap: () {
Navigator.of(context).pop();
},
child: Hero(
tag: 'imgaesView',
child: Container(
width: Get.width,
height: Get.height,
child: Image.network(
'https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/39c71164cc4a455b83ac6f579e2a39c1~tplv-k3u1fbpfcp-watermark.image'),
)),
),
),
transitionsBuilder: (_, Animation<double> animation, __,
Widget child) =>
new SlideTransition(
position: new Tween<Offset>(
begin: Offset(0.0.1.0),
end: Offset(0.0.0.0),
).animate(animation),
child: child),
));
},
child: Container(
margin: EdgeInsets.only(top: 10, left: 10),
width: 200,
height: 140,
child: Image.network(
'https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/39c71164cc4a455b83ac6f579e2a39c1~tplv-k3u1fbpfcp-watermark.image')))));Copy the code
Final linkage effect
The bottom list slides, and the label slides with it.Modify the search_page.dart file and you’re done. The search_hot.dart slide is the same as the home slide I wrote earlier, so I won’t post the code. Same way
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
SearchTop(
dataList: tag,
currentIndex: currentIndex,
onTag: (value) {
setState(() {
currentIndex = value;
});
int index = tag.indexWhere((element) => element == value);
controller.animateToPage(index,
duration: Duration(milliseconds: 500), curve: Curves.easeInOut);
},
),
Expanded(
child: PageView.builder(
controller: controller,
itemBuilder: (context, index) {
return CommonListWiget(
networkApi: (currentPage) async {
Future.delayed(Duration(milliseconds: 500)).then((value) => {
dataList.addAll(['1'.'2'])});return dataList;
},
itemBuilder: (BuildContext context, int position) {
if (position == 0) {
return SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
SearchHot(),
SearchHot(),
SearchHot(),
],
),
);
}
returnSearchItem(type: position); }); }, scrollDirection: Axis.horizontal, onPageChanged: (index) {print(tag[index]);
setState(() {
currentIndex = tag[index];
});
print(currentIndex);
},
itemCount: tag.length,
)),
],
));
}
Copy the code