Android利用Hero实现列表与详情页无缝切换动画

目录
  • 前言
  • 思路
  • 列表元素
  • 详情页面
  • 源码
  • 总结

前言

介绍了几篇 Hero 动画,我们来一个 Hero 动画应用案例。在一些应用中,列表的元素和详情的内容是一致的,这个时候利用 Hero 动画切换到详情会感觉无缝过渡,用户体验会更好。例如本篇我们要实现下面的效果:

Hero 应用:列表与详情切换

思路

上面的效果是列表和详情共用了头像和头像的背景色。二者的组合是一个 Stack 组件,因此可以使用 Hero 组件完成。然后是 Hero 组件的移动,我们先做了水平移动,再做垂直方向移动,这样过渡体验会更好,这种可以用我们自定义的 RectTween 完成。下面是我们的各个部分的实现过程。

列表元素

列表元素我们定义一个 HeroListItem 类,整个列表元素需要点击进入详情,使用 GestureDetector 包裹。然后使用 Row 组件完成横向布局,而头像部分使用的是 Stack 组件。HeroListItem 的 build 方法如下:

Widget build(BuildContext context) {
  return GestureDetector(
    child: Container(
      padding: EdgeInsets.fromLTRB(0, 10.0, 10.0, 10.0),
      child: Row(
        children: [
          Hero(
            tag: heroTag,
            createRectTween: (begin, end) {
              return ListToDetailRectTween(
                begin: begin!,
                end: end!,
              );
            },
            child: ListImage(
              assetImageName: assetImageName,
              imageBgColor: imageBgColor,
            ),
          ),
          SizedBox(
            width: 10.0,
          ),
          Expanded(
            child: Text(
              content,
              style: TextStyle(
                color: Colors.black87,
                fontSize: 18.0,
              ),
              maxLines: 2,
            ),
          ),
        ],
      ),
    ),
    onTap: () {
      Navigator.of(context).push(
        MaterialPageRoute(
          fullscreenDialog: true,
          builder: (context) => ListDetail(
            heroTag: heroTag,
            imageBgColor: imageBgColor,
            assetImageName: assetImageName,
          ),
        ),
      );
    },
  );
}

头像这块因为涉及到背景的边框圆弧处理,单独抽出来一个 ListImage 组件。整个头像是一个 Stack 组件,然后底部的背景 Container 右边的圆弧是通过 BoxDecoration 完成的。后面的 OvalImage 是一个圆形图片包装类,其实就是拿 ClipOval 包裹住 Image 组件就可以了,这里就不贴代码了。

Widget build(BuildContext context) {
  return Stack(
    children: [
      Container(
        height: 90.0,
        width: 110,
        decoration: BoxDecoration(
          color: imageBgColor,
          borderRadius: BorderRadius.only(
            topRight: Radius.circular(45.0),
            bottomRight: Radius.circular(45.0),
          ),
        ),
      ),
      Positioned(
        child: OvalImage(
          assetImageName: assetImageName,
          imageSize: 90.0,
        ),
        left: 20.0,
        top: 0.0,
      )
    ],
  );
}

列表这里的关键其实就是使用 Hero 将头像区域包裹,然后使用了 createRectTween 定义了 Hero 飞行路径。

详情页面

详情页面因为跳转过来是个全屏弹窗的方式,因此需要自己完成返回按钮的操作。实际上详情页顶部就是一个 Stack 组件,组件的背景色和图片和列表保持一样,再在 Stack 组件加上关闭按钮和详情标题即可。这里为了保持页面顶部覆盖状态栏,使用的是 CustomScrollView 实现 (关于 CustomScrollView 可以看这篇:Flutter 实现更有趣的页面滚动效果)。顶部的界面我们定义了一个 ListDetailHeader 组件,代码如下所示。

class ListDetailHeader extends StatelessWidget {
  final heroTag;
  final imageBgColor;
  final assetImageName;
  const ListDetailHeader({
    Key? key,
    required this.heroTag,
    required this.imageBgColor,
    required this.assetImageName,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Hero(
      child: Stack(
        children: [
          Container(
            height: 160.0,
            width: double.infinity,
            decoration: BoxDecoration(
              color: imageBgColor,
            ),
          ),
          Positioned(
            child: Material(
              child: IconButton(
                icon: Icon(
                  Icons.close,
                  color: Colors.white,
                ),
                onPressed: () {
                  Navigator.of(context).pop();
                },
              ),
              color: Colors.transparent,
            ),
            left: 10.0,
            top: 50.0,
            height: 40.0,
          ),
          Positioned(
            child: OvalImage(
              assetImageName: assetImageName,
              imageSize: 90.0,
            ),
            right: 20.0,
            top: 50.0,
          ),
          Positioned(
            child: Material(
              color: Colors.transparent,
              child: Text(
                '这是详情',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 18.0,
                ),
                maxLines: 1,
              ),
            ),
            left: 20,
            top: 100,
          ),
        ],
      ),
      tag: heroTag,
      createRectTween: (begin, end) {
        return ListToDetailRectTween(
          begin: begin!,
          end: end!,
        );
      },
    );
  }
}

这里没什么特别的,但是一开始遇到了一个问题就是发现文本下面会有两条下划线,而且样式也不对。后来百度了一下,发现是因为使用 fullscreenDialog 的时候,实际上是使用的苹果风格的页面,要保持 Material 风格的话,需要使用 Scaffold 或者使用 Material 组件包裹。因此,在 Text 组件上一层加了一个 Material 组件。Material 组件本身的背景色是白色的,为了不影响组件的底色,需要设置它的背景色为transparent

不被 Material 包裹文本

这里的 Hero 组件的 tag 和 createRectTween 和列表保持一致即可,实际的 tag 可以使用列表元素的 id 来设置。

源码

完整源码已经上传至:动画相关代码,代码在 lib/hero/list_to_detail_hero.dart 中。

总结

本篇介绍了一个 Hero 组件的实际应用场景 —— 列表到详情之间利用 Hero 过渡切换。实际上,如果考虑更好的动画效果,还可以结合 AnimatedWidgetAnimatedBuilder 等配合完成。

以上就是Android利用Hero实现列表与详情页无缝切换动画的详细内容,更多关于Android Hero无缝切换动画的资料请关注我们其它相关文章!

(0)

相关推荐

  • Android Flutter实现页面切换转场动画效果

    目录 前言 Hero 动画过程 Hero 基础示例 总结 前言 写了一篇基础的性能优化的内容,继续我们的动画相关的介绍.今天的主角是英雄 —— Hero 组件.Hero 组件非常适合从列表.概览页切换到详情页转场动画场合.因为可以将两个页面的组件串起来动画,体验上会觉得整个操作的连贯性非常好.下面是我们这篇要做的一个效果. 屏幕录制2021-11-09 下午9.39.49.gif Hero 动画过程 Hero 本质是是在不同的路由页面做了一个中转层,然后通过动画完成过渡,下面用4张图是官方演示的

  • Android之Compose页面切换动画介绍

    目录 前因后果 开始尝试 开始撸码 仓促的结尾 前因后果 Compose 正式版已经发布了一个多月了,从 Compose beta 版本发布之后各大网站中热度就一直不减,官方也一直在为开发者们推出学习 Compose 的文章,更加说明了 Android 开发的未来趋势. 在之前我写了 Compose 版本的玩安卓,当然也有 MVVM 版本的,只是不同分支而已,这是 Github地址:https://github.com/zhujiang521/PlayAndroid 但之前一直存在着一个问题,就

  • Android实现千变万化的ViewPager切换动画

    之前写过一篇文章:Android自定义ViewPager实现个性化的图片切换效果,有朋友提出,ViewPager自带了一个setPageTransformer用于设置切换动画~ 本篇文章,将进行以下内容学习: 1.介绍如何使用setPageTransformer设置切换动画: 2.自定义PageTransformer实现个性的切换动画: 3.该方法在SDK11以下的版本不起作用,我们会对其做一定修改,让其向下兼容. 官方示例地址:http://developer.android.com/trai

  • Flutter利用Hero组件实现自定义路径效果的动画

    目录 前言 Hero 的定义 RectTween 自定义RectTween 运行效果 总结 前言 我们在 页面切换转场动画,英雄救场更有趣!介绍了 Hero 动画效果,使用 Hero 用于转场能够提供非常不错的体验.既然称之为英雄,肯定还有其他技能,本篇我们就来探索一下 Hero 动画的返回效果. Hero 的定义 Hero 组件是一个 StatefulWidget,构造方法如下: const Hero({   Key? key,   required this.tag,   this.crea

  • Android实现页面滑动切换动画

    本文实例为大家分享了Android实现页面滑动切换动画的具体代码,供大家参考,具体内容如下 实现两个页面滑动切换,一些相册的效果也是如此 一个Activity的界面配置文件 activity_main.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

  • Android ViewPager实现动画切换效果

    概述 ViewPager是Android开发中使用场景非常频繁的控件,单一的动画效果切换已经越来越不能满足追求个性化的应用中.而ViewPager自身也带有一个接口来处理页面间的动画切换,那就是setPageTransformer.下面我们通过代码来学习动画效果的切换. 实现简单动画切换 代码如下: 1.布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&

  • Android利用Hero实现列表与详情页无缝切换动画

    目录 前言 思路 列表元素 详情页面 源码 总结 前言 介绍了几篇 Hero 动画,我们来一个 Hero 动画应用案例.在一些应用中,列表的元素和详情的内容是一致的,这个时候利用 Hero 动画切换到详情会感觉无缝过渡,用户体验会更好.例如本篇我们要实现下面的效果: Hero 应用:列表与详情切换 思路 上面的效果是列表和详情共用了头像和头像的背景色.二者的组合是一个 Stack 组件,因此可以使用 Hero 组件完成.然后是 Hero 组件的移动,我们先做了水平移动,再做垂直方向移动,这样过渡

  • Android利用RecyclerView实现列表倒计时效果

    最近面试时,面试官问了一个列表倒计时效果如何实现,现在记录一下. 运行效果图 实现思路 实现方法主要有两个: 1.为每个开始倒计时的item启动一个定时器,再做更新item处理: 2.只启动一个定时器,然后遍历数据,再做再做更新item处理. 经过思考,包括性能.实现等方面,决定使用第2种方式实现. 实现过程 数据实体 /** * 总共的倒计时的时间(结束时间-开始时间),单位:毫秒 * 例: 2019-02-23 11:00:30 与 2019-02-23 11:00:00 之间的相差的毫秒数

  • Android通过自定义控件实现360软件详情页效果

    一.概述 最近有不少朋友私聊问应用宝.360软件助手之类的软件详情页怎么做,刚好,最近有时间就模仿360软件助手详情页给大家做个Demo,供大家参考.嗯,关于实现呢,我写了两种方式: 1.ScrollView内嵌软件介绍+ViewPager+ViewPager中是ScrollView,这种方式呢,纯原生,没有涉及到自定义控件,但是这样嵌套呢,涉及到测量以及事件的冲突处理,大家可以自己尝试去做一下,想像起来蛮容易的,做起来其实还是挺费劲的,代码我会给出,核心代码不多,大家自行参考.本文将重点分析第

  • Android模仿知乎的回答详情页的动画效果

    废话不多说,咱们第一篇文章就是模仿"知乎"的回答详情页的动画效果,先上个原版的效果图,咱们就是要做出这个效果 在实现之前,我们先根据上面的动画效果,研究下需求,因为gif帧数有限,所以不是很连贯,推荐你直接下载一个知乎,找到这个界面自己玩玩 ☞当文章往上移动到一定位置之后,最上面的标题栏Bar和问题布局Title是会隐藏的,回答者Author布局不会隐藏 ☞当文章往下移动移动到一定位置之后,原先隐藏的标题栏Bar和问题布局Title会下降显示 ☞当文章往上移动的时候,下部隐藏的Tool

  • Android自定义LinearLayout实现淘宝详情页

    1.简单说明 淘宝详情页就不用我一一介绍了,昨天逛淘宝看到这个效果时,让我想起了去年刚学习Android只会使用现成的时候,当时在网上找了一个这种效果的使用了,并不懂怎么实现的.现在就看到一种效果就想自己实现一下,我想这就是刚接触某个知识时的好奇心吧 说走咱就走啊,本文只是介绍一种实现思路,网上也已经有了很多种实现方式,有问题请指正 效果图(我有很用心的找美女图的) 2.实现思路 继承LinearLayout,设置方向为垂直 控件中有两个ScrollView,至于为什么要使用ScrollView

  • 安卓(android)仿电商app商品详情页按钮浮动效果

    1.效果图如下: 这效果用户体验还是很酷炫,今天我们就来讲解如何实现这个效果. 2.分析 为了方便理解,作图分析 如图所示,整个页面分为四个部分: 1.悬浮内容,floatView 2.顶部内容,headView 3.中间内容,与悬浮内容相同,middleView 4.商品详情展示页面,detailView 因为页面内容高度会超出屏幕,所以用Scrollview实现滚动,悬浮view与scrollview同级,都在一个帧布局或者相对布局中. 当y方向的滚动距离小于中间的内容middleView到

  • Android仿京东、天猫商品详情页

    前言 前面在介绍控件TabLayout控件和CoordinatorLayout使用的时候说了下实现京东.天猫详情页面的效果,今天要说的是优化版,是我们线上实现的效果,首先看一张效果: 项目结构分析 首先我们来分析一下要实现上面的效果,我们需要怎么做.顶部是一个可以滑动切换Tab,可以用ViewPager+Fragment实现,也可以使用系统的TabLayout控件实现:而下面的 View是一个可以滑动拖动效果的View,可以采用网上一个叫做DragLayout的控件,我这里是自己实现了一个,主要

  • Android利用Canvas标点画线并加入位移动画(1)

    本文实例为大家分享了Android利用Canvas标点画线,并加入位移动画的具体代码,供大家参考,具体内容如下 1.背景 最近由于公司业务需要,需要自己实现一个点画线,移动的需求,这自然就想到了利用Canvas进行描点,画线连线. 过程比较简单,查阅了网上文章,发现写的都特别片面,很多人也会遇到类似需求,这里把整个实现过程讲一下,并且在实现过程遇到的一些小坑讲给大家. 先看效果图 其实点击检索,小人可以按照画好的路线进行移动. 具体代码: Canvas画点连线 class DrawView ex

  • Android利用Canvas标点画线并加入位移动画(2)

    本文实例为大家分享了Android利用Canvas标点画线,并加入位移动画的具体代码,供大家参考,具体内容如下 1.背景 继上次公司需求实现Canvas面板标记点,画折现,并利用属性动画进行沿线移动之后,又有了新问题. 发现公司提供的坐标有正值有负值,并且值很大,很容易超出屏幕范围,而且由于我们Canvas坐标方向与正常坐标系不符合,由此发现做的图方向也不对. 2.问题 Canvas坐标系位于屏幕左上角,且Y正向坐标向下,如何转换? 由于坐标有正有负,而Canvas默认只显示正方向,如何解决显示

  • Android模仿实现微博详情页滑动固定顶部栏的效果实例

    前言 最近项目中遇到一个需求,类似微博详情页的效果,通过查找相关的资料终于找了对应的解决方案,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 先来看下我们今天要实现的效果: 滑动固定顶部栏效果图 这段时间公司准备重构一个项目,刚好用到这个效果,我就顺带写了篇文章,关于这个效果网上可以找到一些相关资料的,昨晚看了一些,感觉都不是很好,有点模棱两可的样子,也没提到需要注意的一些关键点,这里来做下整理,由于涉及到公司的代码,这里我就写个简单的Demo来讲解. 简单Demo 传统套路:

随机推荐