热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

flutter模仿微信读书卡片滑动和tab点击联动简单实现

前言:相信大家都用过微信读书APP,里面有卡片滑动和tab点击联动的效果不过微信读书APP都是原生的AndroidiOS分别实现的网上也有各种原生的实现的案

前言:

相信大家都用过微信读书 APP ,里面有卡片滑动和tab点击联动的效果 不过微信读书APP都是原生的Android iOS分别实现的 网上也有各种原生的实现的案例, 我这里就不展开讲了 今天主要给大家分享flutter的实现 废话不多说我们正式开始

效果图:

flutter模仿微信读书卡片滑动和tab点击联动简单实现
微信截图_20200208221710.png

具体实现:

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 学习的新手希望我总结的文章 和代码 能帮助到各位同学


推荐阅读
  • 花瓣|目标值_Compose 动画边学边做夏日彩虹
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Compose动画边学边做-夏日彩虹相关的知识,希望对你有一定的参考价值。引言Comp ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 使用Flutternewintegration_test进行示例集成测试?回答首先在dev下的p ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 本文介绍了在多平台下进行条件编译的必要性,以及具体的实现方法。通过示例代码展示了如何使用条件编译来实现不同平台的功能。最后总结了只要接口相同,不同平台下的编译运行结果也会相同。 ... [详细]
  • Html5-Canvas实现简易的抽奖转盘效果
    本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • Java自带的观察者模式及实现方法详解
    本文介绍了Java自带的观察者模式,包括Observer和Observable对象的定义和使用方法。通过添加观察者和设置内部标志位,当被观察者中的事件发生变化时,通知观察者对象并执行相应的操作。实现观察者模式非常简单,只需继承Observable类和实现Observer接口即可。详情请参考Java官方api文档。 ... [详细]
  • CEPH LIO iSCSI Gateway及其使用参考文档
    本文介绍了CEPH LIO iSCSI Gateway以及使用该网关的参考文档,包括Ceph Block Device、CEPH ISCSI GATEWAY、USING AN ISCSI GATEWAY等。同时提供了多个参考链接,详细介绍了CEPH LIO iSCSI Gateway的配置和使用方法。 ... [详细]
  • 本文介绍了在CentOS 6.4系统中更新源地址的方法,包括备份现有源文件、下载163源、修改文件名、更新列表和系统,并提供了相应的命令。 ... [详细]
  • 本文由编程笔记#小编为大家整理,详细介绍了Flutter中设置分割线Divider的用法,包括高度、缩进和颜色等属性,希望对读者有一定的参考价值。 ... [详细]
  • 本文介绍了如何使用MATLAB调用摄像头进行人脸检测和识别。首先需要安装扩展工具,并下载安装OS Generic Video Interface。然后使用MATLAB的机器视觉工具箱中的VJ算法进行人脸检测,可以直接调用CascadeObjectDetector函数进行检测。同时还介绍了如何调用摄像头进行人脸识别,并对每一帧图像进行识别。最后,给出了一些相关的参考资料和实例。 ... [详细]
  • 今天就跟大家聊聊有关怎么在Android应用中实现一个换肤功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根 ... [详细]
  • 20210304力扣 根据前序遍历和中序遍历确定二叉树 快速排序思想
    力扣根据前序遍历和中序遍历确定二叉树基本思路前序遍历确定根节点是哪个(第一个就是根节点)中序遍历根据已知根节点确定左右子树的元素组成根节点左左子树根节点右右子树再根据前序遍历确定左 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有