整理一下比较有意思的类QQ的UI实现。Nothing that has meaning is easy. Easy doesn’t enter into grown-up life.

darken the background image

很多场景下,我们需要背景图片上面显示文字。如果是白色字体的话,那么暗化图片是必须的,否则会影响文字的显示。可以设置Container的decoration里面的colorFilter属性

decoration: BoxDecoration(
image: DecorationImage(
colorFilter: ColorFilter.mode(Colors.black.withOpacity(0.4), BlendMode.darken),
image: AssetImage("assets/image/me_header_bg.jpg"),
fit: BoxFit.fitWidth,
),

显示的效果如下:原背景图片是亮色的

实现类QQ的卡片展示效果

  • 最外层的Container设置背景浅灰色:
Container(
color: Color.fromRGBO(245, 246, 249, 1),
child: UserToolWidget(tools)
)
  • 主体部分是UserToolWidget
class UserToolWidget extends StatelessWidget {
final List<ToolResp> tools; UserToolWidget(this.tools); @override
Widget build(BuildContext context) {
List<Widget> widgetList = tools.map((tool) => _buildToolItem(context, tool)).toList();
if (tools.length % 3 == 1) {
widgetList.addAll([Container(color: Colors.white), Container(color: Colors.white)]);
}
if (tools.length % 3 == 2) {
widgetList.add(Container(color: Colors.white));
}
return Padding(
padding: const EdgeInsets.all(16),
child: ClipRRect(
borderRadius: BorderRadius.circular(16.0),
child: GridView.count(
crossAxisCount: 3,
physics: ClampingScrollPhysics(),
shrinkWrap: true,
mainAxisSpacing: 1.5,
crossAxisSpacing: 1.5,
children: widgetList,
),
),
);
} Widget _buildToolItem(BuildContext context, ToolResp tool) {
Color color = CommUtil.getColorFromRGBOString(tool.iconColor);
return GestureDetector(
onTap: () => toolHandler.handleToolJump(tool.type, context),
child: Container(
color: Colors.white,
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SvgUtil.withColor(tool.iconName, color),
SizedBox(height: 10),
Text(tool.label, style: TextStyle(color: color)),
],
),
),
);
}
}

实现头像嵌入的效果

Stack(
overflow: Overflow.visible,
alignment: Alignment.topCenter,
children: <Widget>[
GestureDetector(
onTap: () => CommUtil.toBeDev(),
child: Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(20))),
child: Container(
padding: const EdgeInsets.fromLTRB(20, 50, 20, 20),
child: Column(
children: <Widget>[
Text(user.fullName, style: TextStyle(fontSize: 26, fontWeight: FontWeight.w500)),
Text('手机:${user.phone}', style: TextStyle(fontSize: 16)),
SizedBox(height: 6),
QrImage(data: user.phone, version: QrVersions.auto, size: 250.0),
SizedBox(height: 6),
Text("点击卡片更换背景", style: TextStyle(color: Colors.grey))
],
),
),
),
),
Positioned(
top: -40,
child: CircleImageWidget(filename: user.imageUrl, size: 80, borderWidth: 3.0),
)
],
)

实现swipe卡片的功能

  • Swipe的代码
class FirstDaySwipeScreen extends StatelessWidget {
final int index; FirstDaySwipeScreen(this.index); @override
Widget build(BuildContext context) {
return BlocBuilder<FirstDayBloc, FirstDayState>(
builder: (_, FirstDayState state) {
return Center(
child: Container(
height: 370,
child: Swiper(
index: index,
loop: false,
fade: 0.7,
itemBuilder: (_, int index) {
FirstDay firstDay = (state as FirstDayLoadSuccess).firstDays[index];
return FirstDayItemWidget(index, firstDay);
},
itemCount: (state as FirstDayLoadSuccess).firstDays.length,
viewportFraction: 0.8,
scale: 0.9,
),
),
);
},
);
}
}
  • 主体部分是卡片
class FirstDayItemWidget extends StatelessWidget {
final int index;
final FirstDay firstDay; FirstDayItemWidget(this.index, this.firstDay); @override
Widget build(BuildContext context) {
final textColor = CommUtil.getColorByIndex(index);
return Material(
borderRadius: BorderRadius.all(Radius.circular(10)),
clipBehavior: Clip.antiAlias,
child: Container(
alignment: Alignment.topCenter,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomLeft,
colors: <Color>[Color.fromRGBO(255, 227, 243, 1), Colors.white],
),
),
child: Column(
children: <Widget>[
Padding(
child: SvgUtil.convertFromFile('first_love', textColor, 80),
padding: const EdgeInsets.only(top: 45, bottom: 20),
),
Padding(
child: Text('第一次${firstDay.description}', style: TextStyle(fontSize: 16)),
padding: const EdgeInsets.only(bottom: 20),
),
Divider(),
_buildFirstDialogDate(firstDay),
Divider(),
SizedBox(height: 50),
_buildConfirmButton(context, firstDay),
],
),
),
);
} _buildFirstDialogDate(FirstDay firstDay) {
firstDay.firstDateTime = firstDay.firstDateTime ?? DateTime.now();
return StatefulBuilder(builder: (BuildContext buildContext, StateSetter setState) {
return InkWell(
onTap: () {},
child: Container(
alignment: Alignment.topLeft,
padding: const EdgeInsets.only(top: 6, bottom: 6, left: 20, right: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
DateTimeUtil.formatDateTime(firstDay.firstDateTime),
style: TextStyle(fontSize: 16),
),
IconTheme(child: Icon(Icons.keyboard_arrow_right), data: IconThemeData(color: Colors.grey)),
],
),
),
);
});
} _buildConfirmButton(BuildContext context, FirstDay firstDay) {
return StatefulBuilder(
builder: (BuildContext buildContext, StateSetter setState) {
return RaisedButton(
child: Text(firstDay.open ? '取消点亮' : '点亮', style: TextStyle(fontSize: 18)),
shape: StadiumBorder(),
padding: const EdgeInsets.symmetric(horizontal: 100, vertical: 10),
onPressed: () {},
textColor: Colors.white,
color: Color.fromRGBO(253, 111, 193, 1),
);
},
);
}
}

flutter ui---->一些类QQ的实现的更多相关文章

  1. Android代码优化----Application节点的模板写法及UI工具类

    一. MyApplication类的编写: 新建一个类MyApplication,继承自Application.代码如下: MyApplication.java: package com.smyhva ...

  2. iOS开发——项目实战OC篇&类QQ黏性按钮(封装)

    类QQ粘性按钮(封装) 那个,先来说说原理吧: 这里原理就是,在界面设置两个控件一个按钮在上面,一个View在下面(同样大小),当我们拖动按钮的时候显示下面的View,view不移动,但是会根据按钮中 ...

  3. Flutter 即学即用系列博客——04 Flutter UI 初窥

    前面三篇可以算是一个小小的里程碑. 主要是介绍了 Flutter 环境的搭建.如何创建 Flutter 项目以及如何在旧有 Android 项目引入 Flutter. 这一篇我们来学习下 Flutte ...

  4. CSS 伪类(下)结构性伪类\UI伪类\动态伪类和其他伪类 valid check enable child required link visit

      伪类选择器汇总伪类选择器有4种, 结构性伪类\UI伪类\动态伪类和其他伪类. 具体如下 结构性伪类选择器结构性伪类选择器它能够根据元素在文档中的位置选择元素, 这类元素都有个前缀":&q ...

  5. CSS链接四种状态注意顺序、UI伪类选择器的顺序

    css定义超链接是要有先后顺序的.否则,可能会出现某个或某几个样式不起作用的bug.例如:visited与hover顺序颠倒了,则不能显示hover和active的样式了. 正确的顺序: a:link ...

  6. [cocos2dx笔记012]一定简易的UI配置类

    使用cocostudio能够装载编辑好的UI,可是过于复杂.特别是在加截UI后,发现触屏事件有些问题. 假设直接使用程序写死载入UI又过于麻烦.花点时间,添加了一个基于ini的UI配置类,眼下仅仅实现 ...

  7. Flutter UI系统

    我们可以看到,无论是Android SDK还是iOS的UIKit 的职责都是相同的,它们只是语言载体和底层的系统不同而已.那么可不可以实现这么一个UI系统:可以使用同一种编程语言开发,然后针对不同操作 ...

  8. Flutter & UI system & GUI & API & SDK

    Flutter & UI system & GUI & API & SDK https://book.flutterchina.club/chapter14/flutt ...

  9. 全网最详细的一篇Flutter 尺寸限制类容器总结

    Flutter中尺寸限制类容器组件包括ConstrainedBox.UnconstrainedBox.SizedBox.AspectRatio.FractionallySizedBox.Limited ...

  10. Flutter 容器Container类和布局Layout类

    1.布局和容器 [布局]是把[容器]按照不同的方式排列起来. Scaffold包含的主要部门:appBar,body,bottomNavigator 其中body可以是一个布局组件,也可以是一个容器组 ...

随机推荐

  1. app内打开外部第三方瞎下载链接

    Q:我用cordova开发项目,想在app内跳转外部链接,安装了cordova-plugin-inappbrowser后确实可以跳转,但是跳转的页面有个按钮,原本点击会下载app,现在点击后毫无反应, ...

  2. Linux安装ODBC连接SQLServer数据库

    操作系统:Centos7.2 1.下载ODBC安装包 unixODBC-2.3.9.tar.gz freetds-1.3.9.tar.gz 下载这两个压缩包的地址:ftp://ftp.freetds. ...

  3. 结对作业——考研咨询APP

    结对作业--考研资讯系统   102陈同学105潘同学108苏同学 (排版:Markdown) 一.需求分析(NABCD模型) 1. N(Need 需求): 1)想知道每个专业考研可以考哪个专业2)想 ...

  4. matlab 将某文件夹的内容复制到另一文件下

    %% 清空close all;clear;clc; %% 选择文件路径(复制某文件夹下部分文件夹到其他路径)folder = uigetdir('C:\Desktop','请选择文件夹'); %% i ...

  5. mysql创建数据库,用户,授权基操

    # 创建数据库create database test; # 创建用户并设置密码 create user 'test'@'%' identified by '123456';# 设置密码SET PAS ...

  6. MyBatis-Plus使用SQL语句

    项目中碰到一个必须要使用动态SQL的地方, 想着在xml文件中进行一层一层的判断太麻烦了,也不好理解,要是能在Java代码中组织好SQL,进行查询操作 QueryWrapper<object&g ...

  7. 每日一道算法题——斐波那契数列Fibonacci

    题目: 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0,第1项是1),n≤39: 示例1 输入: 4 返回值: 3 代码: 方法一:递归 publi ...

  8. Nginx配置ThinkPHP3.1的PATHINFO模式

    location / {    if (!-e $request_filename) {         rewrite ^/(.*)$ /index.php?$1 last;         bre ...

  9. 解决df.to_csv 时增加重复双引号的问题

    df.to_csv("test.csv", sep='|',quoting=csv.QUOTE_NONE,index=False,header=True) 转载自 df.to_cs ...

  10. spring事务不生效8种原因

    1.数据库引擎不支持事务 这里以 MySQL 为例,其 MyISAM 引擎是不支持事务操作的,InnoDB 才是支持事务的引擎,一般要支持事务都会使用 InnoDB. 根据 MySQL 的官方文档: ...