中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android如何利用Hero實現列表與詳情頁無縫切換動畫

發布時間:2022-06-15 16:03:02 來源:億速云 閱讀:199 作者:iii 欄目:開發技術

這篇文章主要介紹“Android如何利用Hero實現列表與詳情頁無縫切換動畫”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Android如何利用Hero實現列表與詳情頁無縫切換動畫”文章能幫助大家解決問題。

效果:

Android如何利用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

Android如何利用Hero實現列表與詳情頁無縫切換動畫

不被 Material 包裹文本

這里的 Hero 組件的 tag 和 createRectTween 和列表保持一致即可,實際的 tag 可以使用列表元素的 id 來設置。

關于“Android如何利用Hero實現列表與詳情頁無縫切換動畫”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

祁连县| 阿克陶县| 南康市| 武冈市| 定州市| 正蓝旗| 麻栗坡县| 三台县| 雷州市| 伊吾县| 进贤县| 蒙自县| 奉贤区| 金山区| 扶绥县| 湛江市| 合水县| 保亭| 吐鲁番市| 大丰市| 勃利县| 句容市| 嘉祥县| 烟台市| 杭州市| 桃园县| 麻栗坡县| 浠水县| 蛟河市| 彩票| 邵东县| 桃园市| 衡东县| 鸡东县| 三江| 瑞昌市| 甘肃省| 通城县| 同仁县| 洛宁县| 腾冲县|