在这里插入图片描述

前言

启动页是用户打开应用后看到的第一个界面,它不仅承担着品牌展示的功能,还能在应用加载期间为用户提供视觉享受。对于青花瓷App而言,启动页是传递传统文化氛围的绝佳机会。我们将设计一个优雅的启动动画,让青花瓷的图案在屏幕上缓缓绽放。

传统青花瓷的绘制讲究"分水"技法,即通过控制颜料的浓淡来表现层次。我们将这一理念融入动画设计,让图案从淡到浓逐渐显现,仿佛工匠正在瓷器上作画。这种设计既展示了技术能力,又传达了文化内涵。

启动页基础结构

首先,我们创建启动页的基础Widget结构,使用StatefulWidget以支持动画效果。

// lib/screens/splash_screen.dart
import 'package:flutter/material.dart';

class SplashScreen extends StatefulWidget {
  const SplashScreen({super.key});

  
  State<SplashScreen> createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  
  
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 3),
      vsync: this,
    );
  }
}

这段代码创建了启动页的基本框架。我们使用SingleTickerProviderStateMixin来提供动画所需的vsync参数,这能确保动画与屏幕刷新率同步,避免不必要的性能消耗。AnimationController的持续时间设为3秒,这个时长足够展示完整的动画效果,同时不会让用户等待太久。

淡入动画效果

青花瓷图案的显现应该是渐进的,我们使用淡入动画来实现这一效果。

// lib/screens/splash_screen.dart (续)
class _SplashScreenState extends State<SplashScreen>
    with SingleTickerProviderStateMixin {
  late Animation<double> _fadeAnimation;
  
  
  void initState() {
    super.initState();
    _fadeAnimation = Tween<double>(
      begin: 0.0,
      end: 1.0,
    ).animate(CurvedAnimation(
      parent: _controller,
      curve: Curves.easeInOut,
    ));
    _controller.forward();
  }
}

Tween定义了动画的起始值和结束值,从完全透明(0.0)到完全不透明(1.0)。CurvedAnimation添加了缓动曲线,Curves.easeInOut使动画开始和结束时较慢,中间较快,这种节奏更加自然优雅。调用forward()方法启动动画。

OpenHarmony启动页配置

在OpenHarmony端,我们需要配置原生的启动页,以确保在Flutter引擎加载期间也能显示品牌内容。

// ohos/entry/src/main/resources/base/profile/main_pages.json
{
  "src": [
    "pages/SplashPage",
    "pages/Index"
  ]
}

这个配置文件定义了应用的页面路由。SplashPage作为第一个页面会在应用启动时首先加载。OpenHarmony的页面路由系统会按照数组顺序管理页面栈,这使得页面导航变得简单直观。将启动页放在首位确保了用户体验的连贯性。

启动页ArkTS实现

OpenHarmony端的启动页使用ArkTS编写,展示青花瓷的品牌标识。

// ohos/entry/src/main/ets/pages/SplashPage.ets
@Entry
@Component
struct SplashPage {
  @State opacity: number = 0;

  aboutToAppear() {
    animateTo({
      duration: 2000,
      curve: Curve.EaseInOut,
    }, () => {
      this.opacity = 1;
    });
  }

  build() {
    Column() {
      Image($r('app.media.porcelain_logo'))
        .width(200)
        .height(200)
        .opacity(this.opacity)
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#F8F6F0')
  }
}

ArkTS使用声明式UI语法,@State装饰器标记的变量变化时会自动触发UI更新。aboutToAppear是组件生命周期方法,在组件即将显示时调用。animateTo函数创建属性动画,将透明度从0渐变到1。这种实现方式与Flutter的动画理念相似,便于开发者理解和维护。

缩放动画叠加

为了让启动动画更加生动,我们叠加一个缩放效果,模拟青花瓷图案从远处飘来的感觉。

// lib/screens/splash_screen.dart (续)
late Animation<double> _scaleAnimation;


void initState() {
  super.initState();
  _scaleAnimation = Tween<double>(
    begin: 0.8,
    end: 1.0,
  ).animate(CurvedAnimation(
    parent: _controller,
    curve: const Interval(0.0, 0.7, curve: Curves.elasticOut),
  ));
}

缩放动画从0.8倍放大到1.0倍,配合elasticOut曲线产生轻微的弹性效果,仿佛图案轻轻落在瓷面上。Interval限制了动画在整体时间轴的前70%完成,这样缩放动画会比淡入动画更早结束,创造出层次感。多个动画的组合使用是Flutter动画系统的强大之处。

构建启动页UI

现在我们将动画效果应用到实际的UI组件上,构建完整的启动页界面。

// lib/screens/splash_screen.dart (续)

Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: const Color(0xFFF8F6F0),
    body: Center(
      child: AnimatedBuilder(
        animation: _controller,
        builder: (context, child) {
          return Opacity(
            opacity: _fadeAnimation.value,
            child: Transform.scale(
              scale: _scaleAnimation.value,
              child: child,
            ),
          );
        },
        child: const PorcelainLogo(),
      ),
    ),
  );
}

AnimatedBuilder是构建动画UI的高效方式,它只会重建builder函数返回的部分,而child参数传入的Widget不会重建,这优化了性能。OpacityTransform.scale分别应用淡入和缩放效果。背景色使用釉白色,与青花瓷的底色相呼应,营造出典雅的氛围。

页面跳转逻辑

启动动画结束后,需要自动跳转到主页面。我们添加延时跳转的逻辑。

// lib/screens/splash_screen.dart (续)

void initState() {
  super.initState();
  _controller.addStatusListener((status) {
    if (status == AnimationStatus.completed) {
      Navigator.of(context).pushReplacement(
        MaterialPageRoute(
          builder: (context) => const HomePage(),
        ),
      );
    }
  });
}


void dispose() {
  _controller.dispose();
  super.dispose();
}

通过监听动画状态,当动画完成时自动导航到主页。pushReplacement方法会替换当前页面,这样用户按返回键时不会回到启动页。dispose方法中释放AnimationController资源,这是Flutter开发中的重要实践,能够防止内存泄漏。

总结

本篇文章详细介绍了青花瓷App启动页的设计与实现,包括Flutter端的动画效果和OpenHarmony端的原生启动页配置。通过淡入和缩放动画的组合,我们创造了一个优雅的启动体验,让用户从打开应用的第一刻就感受到青花瓷的文化魅力。下一篇文章将介绍应用的底部导航栏设计。欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐