前言:
相信大家都用过微信读书 APP ,里面有卡片滑动和tab点击联动的效果 不过微信读书APP都是原生的Android iOS分别实现的 网上也有各种原生的实现的案例, 我这里就不展开讲了 今天主要给大家分享flutter的实现 废话不多说我们正式开始
效果图:
具体实现:
main.dart 里面我们设置 home: TabNavigator() home加载TabNavigator
import 'package:flutter/material.dart';
import 'tab_navigator.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: TabNavigator()
);
}
}
我们具体看TabNavigatorl里面的实现
import 'package:flutter/material.dart';
import 'content_pager.dart';
/**
* 创建人:xuqing
* 创建时间:2020年2月7日16:26:18
*
*/
class TabNavigator extends StatefulWidget {
TabNavigator({Key key}) : super(key: key);
@override
_TabNavigatorState createState() {
return _TabNavigatorState();
}
}
class _TabNavigatorState extends State {
final _defaultColor=Colors.grey; //未选中
final _activeColor=Colors.blue; //选中的颜色
int _currentIndex=0;
final ContentPagerConteroller _cOntentPagerConteroller=new ContentPagerConteroller();
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0xffedeef0),
Color(0xffe6e7E9),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter
)
),
child: ContentPager(
contentPagerConteroller: _contentPagerConteroller,
onPageChanged: (int index){
setState(() {
_currentIndex=index;
});
},
)
),
bottomNavigationBar: BottomNavigationBar(
items: [
_bottomItem("本周", Icons.folder, 0),
_bottomItem("分享", Icons.explore, 1),
_bottomItem("免费", Icons.donut_small, 2),
_bottomItem("长按", Icons.person, 3),
],
type: BottomNavigationBarType.fixed,
currentIndex: _currentIndex,
onTap: (index){
_contentPagerConteroller.jumpTopage(index);
setState(() {
_currentIndex=index;
});
},
),
);
}
//封装底部的tab
_bottomItem(String title, IconData icon ,int index){
return BottomNavigationBarItem(
icon: Icon(
icon,
color: _defaultColor,
),
activeIcon: Icon(
icon,
color: _activeColor,
),
title: Text(title,style:TextStyle(
color:_currentIndex!=index?_defaultColor:_activeColor
) ,)
);
}
}
TabNavigator 里面我们通过 Decoration 设置背景渐变颜色
然后通过 bottomNavigationBar 设置底部的tab导航 切换的效果
bottomNavigationBar: BottomNavigationBar(
items: [
_bottomItem("本周", Icons.folder, 0),
_bottomItem("分享", Icons.explore, 1),
_bottomItem("免费", Icons.donut_small, 2),
_bottomItem("长按", Icons.person, 3),
],
type: BottomNavigationBarType.fixed,
currentIndex: _currentIndex,
onTap: (index){
_contentPagerConteroller.jumpTopage(index);
setState(() {
_currentIndex=index;
});
},
),
封装底部的tab
//封装底部的tab
_bottomItem(String title, IconData icon ,int index){
return BottomNavigationBarItem(
icon: Icon(
icon,
color: _defaultColor,
),
activeIcon: Icon(
icon,
color: _activeColor,
),
title: Text(title,style:TextStyle(
color:_currentIndex!=index?_defaultColor:_activeColor
) ,)
);
}
到此我们的底部tab导航我们就实现了
接下来我们实现卡片切换的效果
我们在body里面加载了 ContentPager
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0xffedeef0),
Color(0xffe6e7E9),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter
)
),
child: ContentPager(
contentPagerConteroller: _contentPagerConteroller,
onPageChanged: (int index){
setState(() {
_currentIndex=index;
});
},
)
),
在 ContentPager 类里面 放置一个 PageView来装载所有的滑动的 Widget
Column(
children: [
Expanded(
child: PageView(
onPageChanged: widget.onPageChanged,
controller: _pageController,
children: [
_wrapItem(0),
_wrapItem(1),
_wrapItem(2),
_wrapItem(3),
],
),
)
],
);
封装 _wrapItem 方法根据下标index来返回对应的Widget
Widget _wrapItem(int index){
return Container(
child: _listwidget[index],
);
}
定义一个 List_listwidget 集合来装载具体的Widget
static List_listwidget=[
ThisWeekPage(),
SharePage(),
FreeofChargePage(),
LongpressPage(),
];
定义两个成员变量 onPageChanged contentPagerConteroller 用来回调
给 TabNavigator
final ValueChangedonPageChanged;
final ContentPagerConteroller contentPagerConteroller;
onPageChanged 用来控制 滑动跟tab联动
contentPagerConteroller 用来控制点击底部的tab上的卡片Widget 切换
具体调用
onPageChanged 调用
child: ContentPager(
contentPagerConteroller: _contentPagerConteroller,
onPageChanged: (int index){
setState(() {
_currentIndex=index;
});
},
)
_contentPagerConteroller 调用
type: BottomNavigationBarType.fixed,
currentIndex: _currentIndex,
onTap: (index){
_contentPagerConteroller.jumpTopage(index);
setState(() {
_currentIndex=index;
});
},
完整代码实现
import 'package:flutter/material.dart';
import 'pages/thisweek_page.dart';
import 'pages/share_page.dart';
import 'pages/freeofcharge_page.dart';
import 'pages/longpress_page.dart';
/***
*
* 创建人:xuqing
* 创建时间:2020年2月8日23:35:18
* 类说明: 卡片页面
*
*
*
*/
class ContentPager extends StatefulWidget {
final ValueChangedonPageChanged;
final ContentPagerConteroller contentPagerConteroller;
//构造方法 可选参数
ContentPager({Key key, this.onPageChanged, this.contentPagerConteroller}) : super(key: key);
@override
_ContentPagerState createState() {
return _ContentPagerState();
}
}
class _ContentPagerState extends State {
//视图比例
PageController _pageCOntroller=PageController(
viewportFraction: 0.8,
);
static List_colorlist=[
Colors.blue,
Colors.red,
Colors.deepOrange,
Colors.teal,
];
static List_listwidget=[
ThisWeekPage(),
SharePage(),
FreeofChargePage(),
LongpressPage(),
];
@override
void initState() {
// TODO: implement initState
if(widget.contentPagerConteroller!=null){
widget.contentPagerConteroller._pageCOntroller=_pageController;
}
super.initState();
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return Column(
children: [
Expanded(
child: PageView(
onPageChanged: widget.onPageChanged,
controller: _pageController,
children: [
_wrapItem(0),
_wrapItem(1),
_wrapItem(2),
_wrapItem(3),
],
),
)
],
);
}
Widget _wrapItem(int index){
return Container(
child: _listwidget[index],
);
}
}
class ContentPagerConteroller{
PageController _pageController;
void jumpTopage(int page){
//dart 编程技巧 安全调用
_pageController?.jumpToPage(page);
}
}
具体的
ThisWeekPage(),
SharePage(),
FreeofChargePage(),
LongpressPage(),
这些 切换的 Widget我这边就没有做过多的处理 只是的设置了一个背景颜色和一个Text 用来测试实现 效果 有需要拓展的同学可以跟距源代码具体的实现
源码下载链接:https://gitee.com/qiuyu123/tabandpageview.git
最后总结:
这个效果主要是 通过 bottomNavigationBar 配合PageView 来实现卡片的页面的滑动切换和底部tab点击切换 然后通过回调方法来操作调用的联动
我也是一个flutter 学习的新手希望我总结的文章 和代码 能帮助到各位同学