# 都是知识点-flutter基础知识点

1、如何执行异步任务(async task).

这里只提最简单的一种(加关键词await,async)。假设我们有个http请求,很耗时,就需要用异步执行此任务。

dart 复制代码
  Future<dynamic>? getWeatherDataByCity(Map<String, dynamic> params) async {
      http.Response response = await http.get(Uri.http(baseWeatherUrl, '/data/2.5/weather',
          params));
      print(response.statusCode);
      if (response.statusCode == 200) {
        print(response.body);
        var json = jsonDecode(response.body);
        return json;
      }
      }
  }

注意,在dart中执行异步任务,需要使用 awaitasync 关键词。 await 用于修饰调用方法, async则在调用方法名后添加。

2、关于 Futures 的一些用法

对于await 返回的对象,我们一般用 Future包裹一下。拿到后,既可以直接使用。例如:

dart 复制代码
var weatherData = await getCityWeather(typedName);

上面http接口,返回的是一个json对象,json对象返回类型 Future, 这是一个可用json对象。假设返回body的json串是:

json 复制代码
{
 "coord":{"lon":114.2667,"lat":30.5833},
 "weather":[{"id":501,"main":"Rain","description":"moderate rain","icon":"10d"}]
}

获取json字段就很容易:

dart 复制代码
var main = weatherData['weather'] ['main'];

3、在Dart 怎么用 http package.

其实 dart 已经提供了开源的 http 包给大家使用。就在这里: 【HTTP】dart 的 http 库 具体用法其实上面讲异步时已经展示过了:

dart 复制代码
  final String baseWeatherUrl = "api.openweathermap.org";
  Map<String, dynamic> params = HashMap<String, String>();
  params["lat"]= '$lat';
  params["lon"]= '$lon';
  params["appid"]= kApiKey;
  http.Response response = await http.get(Uri.http(baseWeatherUrl, '/data/2.5/weather', params));
      print(response.statusCode);

4、什么是API,怎么从APIs获取数据?

application interface,一般返回服务器的数据,数据格式有很多。所以需要我们和服务器开发人员商量好。本例,我们返回 json 格式。获取方式参考上面的方法。

5、JSONs 是什么?我们在dart中如何解析JSON?

json 是一种指定格式的数据字符串。他可以是简单地键值对。例如:

dart 复制代码
{'id':222, 'name':'tom'}

也可以是嵌套很深的对象:

dart 复制代码
{
 "coord":{"lon":114.2667,"lat":30.5833},
 "weather":[{"id":501,"main":"Rain","description":"moderate rain","icon":"10d"}]
}

dart 中,我们引入 convert 包的 jsonDecode 方法对json字符串进行解析。解析返回的对象,一般是Map<String, dynamic>对象。获取值就可以用map对象的方式获取即可。

dart 复制代码
var coord = params['coord'];

假如我们有2个页面,当前页面: WeatherLoadingScreen , 和要跳转的页面:LocationScreen, 有个数据传递给 LocationScreen,目前有2种方法可以实现:

  1. 我们可以直接在 LocationScreen 构造方法里增加参数 weatherData
dart 复制代码
Navigator.push(context,
      MaterialPageRoute(builder: (context)=>LocationScreen(
        weatherData: weatherData,
      )));

LocationScreen 里,我们就可以用 weatherData 字段。

  1. Navigator.push() 方法带上参数:arguments. 可以参考这篇文章: navigator 带参数传递

  2. 返回参数 如果我们希望 LocationScreen,结束,返回参数: 可以跳转时,获取一下返回值:

dart 复制代码
var cityName = await Navigator.push(context, MaterialPageRoute(
                          builder: (context) {
                            return CityScreen();
                          },
                        ),
                      );

返回时,加上参数 cityName

dart 复制代码
class CityScreen {
void build(BuildContext context) {
    Navigator.pop(context, cityName);
}
}

在上面 cityName 就得到此返回值。

7、dart 如何处理 exceptions(使用 try/catch/throw.)

如果代码出错了,类似 java 的异常处理,dart 也会有异常处理机制。dart 的写法如下:

dart 复制代码
try {
      Map<String, dynamic> params = HashMap<String, String>();
      params["lat"]= '$lat';
      params["lon"]= '$lon';
      params["appid"]= kApiKey;
      http.Response response = await http.get(
          Uri.http(baseWeatherUrl, '/data/2.5/weather', params));
      print(response.statusCode);
      if (response.statusCode == 200) {
        print(response.body);
        var json = jsonDecode(response.body);
        return json;
      }
    } catch(e) {
      print(e);
      return null;
    }

throw 一个异常也很简单:

dart 复制代码
// define an exception
class ClientException implements Exception {
  final String message;

  /// The URL of the HTTP request or response that failed.
  final Uri? uri;
  ClientException(this.message, [this.uri]);

  @override
  String toString() {
    if (uri != null) {
      return 'ClientException: $message, uri=$uri';
    } else {
      return 'ClientException: $message';
    }
  }
}

  void _checkResponseSuccess(Uri url, Response response) {
    if (response.statusCode < 400) return;
    var message = 'Request to $url failed with status ${response.statusCode}';
    if (response.reasonPhrase != null) {
      message = '$message: ${response.reasonPhrase}';
    }
    throw ClientException('$message.', url); // 抛出一个异常
  }

8、StatefulWidget的生命周期方法和重载.

android的activity都是有生命周期的,onCreate(),onResume(), onDestroy()等方法展示了 Activity的创建,暂停,销毁等。flutter 的StatefullWidget也有一些生命周期方法。 例如:

  1. initState() Widget的state对象创建时,会调用此方法,表示初始化
  2. didUpdateWidget() ,widget 的配置变化,会调用此方法。
  3. dispose()

9、如何使用定位获取经纬度

在android manifest.xml中需要配置定位权限。

xml 复制代码
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="co.example.ooh">
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>

ios的plist文件也需要配置:

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>This app needs access to location when open.</string>

然后咱获取定位即可:

dart 复制代码
class Location {
  late double _latitude;
  late double _longitude;
  StreamSubscription<Position>? positionStream;

  Future<void> getCurrentLocation() async {
    try {
      LocationPermission permission = await Geolocator.checkPermission();
      if (permission == LocationPermission.denied) {
        permission = await Geolocator.requestPermission();
        if (permission == LocationPermission.denied) {
          return Future.error('Location permissions are denied');
        }
      }

      if (permission == LocationPermission.deniedForever) {
        return Future.error(
            'Location permissions are permanently denied, we cannot request permissions.');
      }
      // 获取当前经纬度
      Position? position = await Geolocator.getLastKnownPosition();
      positionStream = await Geolocator.getPositionStream().listen((event) {
        // 暂停
        positionStream?.pause();
      });
      if (position !=null) {
        _latitude = position.latitude;
        _longitude = position.longitude;
      } else {
        _latitude = 0;
        _longitude = 0;
      }
      positionStream?.cancel();
    } catch (e) {
      print(e);
      _latitude = 0;
      _longitude = 0;
    }
  }

  double getLat() {
    return _latitude;
  }

  double getLon() {
    return _longitude;
  }
}

10、输入框TextField Widget获取用户输入:

dart 复制代码
Container(
  padding: EdgeInsets.all(20.0),
  child: TextField(
    style: TextStyle(
      color: Colors.black,
    ),
    decoration: kTextFieldInputDecoration,
    onChanged: (value) {
      cityName = value; // 获取输入框的文本
    },
  ),
),
相关推荐
sunly_1 分钟前
Flutter:AnimatedIcon图标动画,自定义Icon通过延时Interval,实现交错式动画
flutter
嘟嘟叽1 分钟前
初学 flutter 问题记录
flutter
__WanG2 分钟前
Flutter将应用打包发布到App Store
前端·flutter·ios
leluckys5 分钟前
flutter 专题十七 Flutter Flar动画实战
前端·flutter
sunly_1 小时前
Flutter:AnimatedBuilder自定义显示动画
flutter
leluckys1 小时前
flutter 专题十一 Fair原理篇Fair逻辑动态化架构设计与实现
flutter
Jinkey17 小时前
FlutterBasic - GetBuilder、Obx、GetX<Controller>、GetxController 有啥区别
android·flutter·ios
Summer不秃21 小时前
Flutter之使用mqtt进行连接和信息传输的使用案例
前端·flutter
旭日猎鹰21 小时前
Flutter踩坑记录(二)-- GestureDetector+Expanded点击无效果
前端·javascript·flutter
sunly_21 小时前
Flutter:AnimatedSwitcher当子元素改变时,触发动画
flutter