【flutter】flutter基础总结1
flutter基础总结1
1、如何执行异步任务(async task).
假设我们有个http请求,当然很耗时,就需要用异步执行此任务。
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中执行异步任务,需要使用 await 和 async 关键词。
await 用于修饰调用方法, async则在调用方法名后添加。
2、关于 Futures 的一些用法
对于await 返回的对象,我们一般用 Future包裹一下。拿到后,既可以直接使用。例如:
var weatherData = await getCityWeather(typedName);
上面http接口,返回的是一个json对象,json对象返回类型 Future, 这是一个可用json对象。假设返回body的json串是:
{"coord":{"lon":114.2667,"lat":30.5833},"weather":[{"id":501,"main":"Rain","description":"moderate rain","icon":"10d"}]
}
获取json字段就很容易:
var main = weatherData['weather'] ['main'];
3、在Dart 怎么用 http package.
其实 dart 已经提供了开源的 http 包给大家使用。就在这里:
【HTTP】dart 的 http 库
具体用法其实上面讲异步时已经展示过了:
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 是一种指定格式的数据字符串。他可以是简单地键值对。例如:
{'id':222, 'name':'tom'}
也可以是嵌套很深的对象:
{"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对象的方式获取即可。
var coord = params['coord'];
6、在页面切换时,如何用 Navigator 切换页面和传递参数。
假如我们有2个页面,当前页面: WeatherLoadingScreen, 和要跳转的页面:LocationScreen, 有个数据传递给 LocationScreen,目前有2种方法可以实现:
- 我们可以直接在 LocationScreen 构造方法里增加参数
weatherData
Navigator.push(context,MaterialPageRoute(builder: (context)=>LocationScreen(weatherData: weatherData,)));
类 LocationScreen
里,我们就可以用 weatherData 字段。
-
Navigator.push()
方法带上参数:arguments
.
可以参考这篇文章:
navigator 带参数传递 -
返回参数
如果我们希望 LocationScreen,结束,返回参数:
可以跳转时,获取一下返回值:
var cityName = await Navigator.push(context, MaterialPageRoute(builder: (context) {return CityScreen();},),);
返回时,加上参数 cityName
:
class CityScreen {
void build(BuildContext context) {Navigator.pop(context, cityName);
}
}
在上面 cityName
就得到此返回值。
7、dart 如何处理 exceptions(使用 try/catch/throw.)
如果代码出错了,类似 java
的异常处理,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 一个异常也很简单:
// 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]);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也有一些生命周期方法。
例如:
- initState() Widget的state对象创建时,会调用此方法,表示初始化
- didUpdateWidget() ,widget 的配置变化,会调用此方法。
- dispose()
9、如何使用定位模糊获取经纬度
在android manifest.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 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>
然后咱获取定位即可:
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获取用户输入:
Container(padding: EdgeInsets.all(20.0),child: TextField(style: TextStyle(color: Colors.black,),decoration: kTextFieldInputDecoration,onChanged: (value) {cityName = value; // 获取输入框的文本},),
),