Flutter World Time应用:构建跨平台时钟,深入探索Flutter核心概念⏰

前言 🌟

Flutter的灵活性和强大性使其成为跨平台应用程序开发的热门选择。在这篇博客中,我们将通过构建一个简单而实用的World Time应用程序,深入了解Flutter的核心概念。从页面小部件到异步方法,再到自定义类的使用,让我们一起踏上这段富有启发性的Flutter之旅。

启动World Time应用程序 🌍⏰

创建页面小部件 🛠️

  1. 创建lib/pages文件夹,用于存放页面小部件。
  2. 创建home.dartchoose_location.dartloading.dart文件。
  3. 在每个文件中创建基本的Stateful Widget,构建简单的UI。
// home.dart
import 'package:flutter/material.dart';

class Home extends StatefulWidget {
  
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Text('Home Screen'),
      ),
    );
  }
}

// choose_location.dart
import 'package:flutter/material.dart';

class ChooseLocation extends StatefulWidget {
  
  _ChooseLocationState createState() => _ChooseLocationState();
}

class _ChooseLocationState extends State<ChooseLocation> {
  
  Widget build(BuildContext context) {
    return Scaffold(
      body: Text('Choose Location Screen'),
    );
  }
}

// loading.dart
import 'package:flutter/material.dart';

class Loading extends StatefulWidget {
  
  _LoadingState createState() => _LoadingState();
}

main.dart中导入这些页面小部件 🚀

import 'package:flutter/material.dart';
import 'package:world_time/pages/home.dart';
import 'package:world_time/pages/choose_location.dart';
import 'package:world_time/pages/loading.dart';

void main() {
  runApp(MaterialApp(
    home: Home(),
  ));
}

创建基本路由 🗺️

  1. MaterialApp中创建routes属性,其值是一个Map,包含不同路由的命名和对应的函数。
  2. 函数的参数是context,返回要加载的Widget。
  3. 使用Navigator.pushNamed进行路由导航。
  4. 使用Navigator.pop在栈上弹出当前路由。
MaterialApp(
  initialRoute: '/',
  routes: {
    '/': (context) => Loading(),
    '/home': (context) => Home(),
    '/location': (context) => ChooseLocation(),
  },
);

在定义路由表时,不应该在每个路由定义的末尾使用分号 ;而应该使用逗号 ,

'/home' 是一个字符串,而 '/home': (context) => Home() 是一个 Dart 映射(Map)中的一个键值对,键是字符串 '/home',值是一个 Dart 函数。

导航到新路由 🛤️

在选择位置的屏幕中,使用Navigator.pushNamed导航到新的路由(Choose Location)。

TextButton.icon(
  onPressed: () {
    Navigator.pushNamed(context, '/location');
  },
  icon: Icon(Icons.edit_location),
  label: Text('Edit Location'),
)

在 Flutter 中,导航通常涉及使用 Navigator 来管理页面(Route)的堆栈,而 Navigatorpush 方法期望接受一个 Route 对象而不是直接的字符串。

在新路由中添加AppBar 🌐

在选择位置的屏幕中,通过添加AppBar提供返回上一页的功能。

Scaffold(
  appBar: AppBar(
    backgroundColor: Colors.blue[900],
    title: Text('Choose a Location'),
    centerTitle: true,
    elevation: 0,
  ),
  backgroundColor: Colors.grey[200],
  // Other content...
)

路由的压栈与出栈 🔄

  • Flutter应用程序中,路由可以想象为屏幕的栈,通过Navigator.pushNamed压入新路由,通过Navigator.pop出栈。
  • 出栈时,可以返回到前一个路由,即前一个屏幕。

使用initState和setState 🔄

ChooseLocation页面中,演示使用initStatesetState

class _ChooseLocationState extends State<ChooseLocation> {
  int counter = 0;

  
  void initState() {
    super.initState();
    print('initState function ran');
  }

  
  Widget build(BuildContext context) {
    print('build function ran');
    return Scaffold(
      appBar: AppBar(
        title: Text('Choose a Location'),
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            setState(() {
              counter += 1;
            });
            print('Counter is $counter');
          },
          child: Text('Counter is $counter'),
        ),
      ),
    );
  }
}

World Time自定义类 🌐⏰

创建WorldTime类 🌐

  • lib文件夹下创建一个名为services的新文件夹,用于存放服务类。
  • services文件夹下创建一个名为world_time.dart的新Dart文件,用于存放WorldTime类。
  • world_time.dart文件中导入所需的包:httpdart:convert
  • 创建WorldTime类,包含locationtimeflagURL属性。
import 'package:http/http.dart' as http;
import 'dart:convert';

class WorldTime {
  String location;
  String time;
  String flag;
  String URL;

  WorldTime({
    required this.location,
    required this.flag,
    required this.URL,
  });

  Future<void> getTime() async {
    // 之前的逻辑...
    // 设置time属性
    time = now.toString();
  }
}

将逻辑移动到WorldTime类 🚚

  • 将原先get time函数中的逻辑移动到WorldTime类中。
  • WorldTime类中,使用await等关键字使函数变为异步方法。
  • get time函数中设置time属性,以便在使用WorldTime实例时获取时间。
Future<void> getTime() async {
  http.Response response = await http.get(URL);
  Map<String, dynamic> data = jsonDecode(response.body);

  // 原先的逻辑...

  // 设置time属性
  time = now.toString();
}

使用WorldTime类 🌐

  • 在加载屏幕(loading.dart)中导入WorldTime类。
  • 创建setupWorldTime函数,用于实例化WorldTime并获取时间。
  • 使用`

set state`更新UI以显示获取到的时间。

class _LoadingState extends State<Loading> {
  String time = 'Loading';

  void setupWorldTime() async {
    WorldTime instance = WorldTime(
      location: 'Berlin',
      flag: 'Germany.png',
      URL: '/Europe/Berlin',
    );

    await instance.getTime();

    // 使用 set state 更新 UI
    setState(() {
      time = instance.time;
    });
  }

  
  void initState() {
    super.initState();
    setupWorldTime();
  }

  // 构建 UI...
}

World Time应用程序启动成功 🎉

你已经成功地创建了World Time应用程序的基本框架,并使用自定义的WorldTime类获取了实际时间数据。通过路由、异步方法和状态管理,我们建立了一个简单而强大的Flutter应用程序。🚀

结语 🌐⏰

通过完成World Time应用程序的搭建,我们不仅学到了如何使用Flutter创建应用,还深入了解了UI构建、路由管理、异步编程等关键概念。这只是Flutter学习之旅的开端,希望你能以这为起点,持续挑战更高级的主题,成为精湛的Flutter开发者。感谢你的阅读,愿你在这个技术的舞台上取得卓越的成就!🚀

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值