フラッターアーキテクチャ
ハローリーダー!フラッタは、特にモバイルフィールドでは、長年にわたって普及している.それはほとんど簡単に学習し、大幅に開発の速度を高めることができます.フラッターの初心者には、どうやって自分のコードをきれいにするのですか?どのように、私は州を管理しますか?どうやってコードを構成するのですか?
記事では、あなたのコードをきれいにする方法を示しています.もちろん、柔軟な構造で、あなたによって変更されたり編集されたりすることができます.これは、懸念の分離を考慮します(もちろん、大きな問題です).
我々は何を作成するつもりです
データ ミックス モデル プロバイダ スクリーン Utils 州の管理のために、我々はHTTP呼び出しのためにプロバイダープラグインとDIOでプロバイダーパターンを利用するつもりです.これを使用するには、Pubspecの依存関係を追加する必要があります.YAMLフォルダ
プロバイダhttps://pub.dev/packages/provider ]
diohttps://pub.dev/packages/dio ]
プロセス
記事では、あなたのコードをきれいにする方法を示しています.もちろん、柔軟な構造で、あなたによって変更されたり編集されたりすることができます.これは、懸念の分離を考慮します(もちろん、大きな問題です).
我々は何を作成するつもりです
物事を非常に簡単にするには、我々は天気データを取得し、画面上のテキストとしていくつかの表示をOpenWaveTherapAPIを使用してアプリケーションを作成する予定です.最終的なアプリケーションは以下のとおりです
プロジェクト設定
このプロジェクトは、私たちのlibディレクトリに合計6個のフォルダを持つ予定です
このプロジェクトは、私たちのlibディレクトリに合計6個のフォルダを持つ予定です
プロバイダhttps://pub.dev/packages/provider ]
diohttps://pub.dev/packages/dio ]
プロセス
当社のアプリケーションの流れは、それぞれの特定のタスクを実行する別のクラスに分かれています.
私はちょうどコードを示して、クラスが何をするかについて説明します、そして、これの終わりに、私は詳細に全体のプロセスを説明します.
データクラス
データフォルダでは、我々は2つのクラスweather_data
and weather_repo
The weather_data
class is responsible for fetching the weather data from the api, and returning the data to the repo class.
The getWeather
method takes in a dio
parameter that will be parse in by the view home_screen
.
When the data has been gotten successfully from the api the weather class feeds the status of the response and the actual data to the Operation
class and returns an instance of this class to the Weather Repo
気象データ
import 'package:dio/dio.dart';
import 'package:weather_art/models/country_response_model.dart';
import 'package:weather_art/utils/operation.dart';
class WeatherData{
Future<Operation> getWeather(Dio dio) async{
try{
var response = await dio.get(
'http://api.openweathermap.org/data/2.5/weather?q=lagos&appid={api_key}',
).timeout(Duration(minutes: 2), onTimeout: () async{
return Response(
data: {"message": "Connection Timed out. Please try again"},
statusCode: 408);
}).catchError((error) {
return Response(
data: {"message": "Error occurred while connecting to server"},
statusCode: 508);
});
if(response.statusCode == 508 || response.statusCode == 408){
return Operation(response.statusCode, response.data);
}else{
WeatherResponse data = WeatherResponse.fromJson(response.data);
return Operation(response.statusCode, data);
}
}catch(err){
//catch err
}
}
}
}
final countryData = WeatherData();
The weather_repo
クラスはデータクラスを呼び出し、データを返すのを待つものです.
天気予報
import 'package:dio/dio.dart';
import 'package:weather_art/data/weather_data.dart';
import 'package:weather_art/utils/operation.dart';
class _WeatherRepo{
getWeatherData(Dio dio, OperationCompleted countryDataCompleted){
countryData.getWeather(dio).then((data) => countryDataCompleted(data));
}
}
_WeatherRepo countryRepo = _WeatherRepo();
mixinクラス
mixinフォルダでは、1つのクラスを作成し、それを呼び出しますhome_helper
. このクラスは、プロバイダによって、取得したデータに応じてビューの状態を変更します.これは、状態を変更するためのコードがビュー自体から分離され、ビュー内で行われるロジックを減らすことを確認します
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:weather_art/data/weather_repo.dart';
import 'package:weather_art/models/country_response_model.dart';
import 'package:weather_art/providers/home_provider.dart';
import 'package:weather_art/utils/operation.dart';
mixin HomeHelper{
BuildContext _authContext;
doGetWeather(Dio dio, BuildContext context){
_authContext = context;
Provider.of<HomeProvider>(_authContext, listen: false).updateIsLoading(true);
weatherRepo.getWeatherData(dio, _weatherDataCompleted);
}
_weatherDataCompleted(Operation operation){
if(operation.code == 408 || operation.code == 508){
//handle time out
Provider.of<HomeProvider>(_authContext, listen: false).updateIsLoading(false);
print('connection timed out');
}else{
WeatherResponse weatherResponse = operation.result;
Provider.of<HomeProvider>(_authContext, listen: false).updateWeather(weatherResponse);
Provider.of<HomeProvider>(_authContext, listen: false).updateIsLoading(false);
}
}
}
モデルクラス
このフォルダで我々の天気モデルを作成します
// To parse this JSON data, do
//
// final weatherResponse = weatherResponseFromJson(jsonString);
import 'dart:convert';
WeatherResponse weatherResponseFromJson(String str) => WeatherResponse.fromJson(json.decode(str));
String weatherResponseToJson(WeatherResponse data) => json.encode(data.toJson());
class WeatherResponse {
WeatherResponse({
this.weather,
this.main,
});
List<Weather> weather;
Main main;
factory WeatherResponse.fromJson(Map<String, dynamic> json) => WeatherResponse(
coord: Coord.fromJson(json["coord"]),
weather: List<Weather>.from(json["weather"].map((x) => Weather.fromJson(x))),
main: Main.fromJson(json["main"]),
);
Map<String, dynamic> toJson() => {
"coord": coord.toJson(),
"weather": List<dynamic>.from(weather.map((x) => x.toJson())),
"main": main.toJson(),
};
}
class Main {
Main({
this.temp,
});
double temp;
factory Main.fromJson(Map<String, dynamic> json) => Main(
temp: json["temp"].toDouble(),
);
Map<String, dynamic> toJson() => {
"temp": temp,
};
}
class Weather {
Weather({
this.main,
this.description,
});
String main;
String description;
factory Weather.fromJson(Map<String, dynamic> json) => Weather(
main: json["main"],
description: json["description"],
);
Map<String, dynamic> toJson() => {
"main": main,
"description": description,
};
}
プロバイダーフォルダ
ここで2つのファイルを作成しますHomeProvider
and AppProvider
ホームプロバイダ
import 'package:flutter/foundation.dart';
import 'package:weather_art/models/country_response_model.dart';
class HomeProvider extends ChangeNotifier{
bool isLoading = false;
List<WeatherResponseModel> weatherList = [];
WeatherResponseModel weatherResponse;
void updateIsLoading(bool isLoadingGotten){
isLoading = isLoadingGotten;
notifyListeners();
}
void updateWeather(WeatherResponseModel weatherResponseGotten){
weatherResponse = weatherResponseGotten;
}
}
アプリプロバイダ
import 'package:dio/dio.dart';
class AppProvider{
Dio dio = Dio();
}
スクリーンフォルダ
これは私たちのビューがどこにあるか、ここでファイルを作成し、それを呼び出しますhome_screen
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:weather_art/mixin/home_helper.dart';
import 'package:weather_art/providers/app_provider.dart';
import 'package:weather_art/providers/home_provider.dart';
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> with HomeHelper{
@override
void initState() {
// TODO: implement initState
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
doGetWeather(
Provider.of<AppProvider>(context, listen: false).dio,
context
);
});
}
@override
Widget build(BuildContext context) {
return Consumer(
builder: (BuildContext context, HomeProvider homeProvider, Widget child){
return Scaffold(
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: decideLayout(homeProvider),
),
);
}
);
}
Widget decideLayout(HomeProvider homeProvider){
if(homeProvider.isLoading){
return Center(
child: CircularProgressIndicator(),
);
}else if(homeProvider.isLoading == false && homeProvider.weatherResponse == null){
return Center(
child: Text(
'Null',
style: TextStyle(
fontSize: 14
),
),
);
}else{
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Weather in Lagos',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold
),
),
Text(
'Looks Like ${homeProvider.weatherResponse.weather[0].main}',
style: TextStyle(
fontSize: 14
),
),
Text(
'Description ${homeProvider.weatherResponse.weather[0].description}',
style: TextStyle(
fontSize: 14
),
),
Text(
'Temp ${homeProvider.weatherResponse.main.temp.toString()}',
style: TextStyle(
fontSize: 14
),
),
],
);
}
}
}
Utilsフォルダ
このフォルダにはクラス操作が含まれます.あなたはちょうどあなたのコードでこれをコピーして、これを通り過ぎることができます.クラスは2つのparamsを受け入れます.レスポンスコードと応答データ.このクラスは、操作が完了したかどうかをチェックするために使用されるtypedefまたはコールバックです.
import 'package:flutter/material.dart';
typedef OperationCompleted(Operation operation);
class Operation {
final dynamic _result;
final int code;
Operation(this.code, this._result);
bool get succeeded => code >= 200 && code <= 226;
dynamic get result => _result;
}
流れ
私たちは、すべてのコードとクラスは、このパターンに関与して見てきました、それぞれのいくつかの説明で、今私は一緒にすべてを結合させ、アプリケーションとのユーザーの相互作用に従うことによって、1つの画像を描画し、各接続で何が起こるかを伝える.
ユーザーは彼が何をすべきかを探している彼の電話をクリックしています.そして、彼は「何が今日のようになるかについて天気です」と言います、そして、彼は我々のアプリを開けるために進みます.ユーザーは私達のhome_screen
, 我々home_screen
と呼ばれるmixinを使用しますHomeHelper
また、HomeProvider
それ自身の状態を管理する.
The isLoading
にHomeProvider
ユーザーが何かがロードされていることを示す循環的な進展を見るように、クラスはfalseです.これが起こっている間initState
呼び出しdoGetWeather
に必要なパラメータを指定します.The doGetWeather
ミックスからのHomeHelper
. The doGetWeather
呼び出しweatherRepo.getWeatherData
は_WeatherRepo
クラス.これはgetWeather
にWeatherData
クラスFuture
したがって、このメソッドは、何かをgetWeather
. getWeather
はAPIからデータを取得し、Operation
. Operation
ステータスコードとAPIからのデータである2つのパラメータを受け入れます.操作がgetWeather
, その後、データが後方に渡されます.
我々は、Repoクラスがまだ若干のデータを予想すると思い出すべきです.then
repoクラスを呼び出し、データをcountryDataCompleted
, これは順番に_weatherDataCompleted
インHomeHelper
. ここでは、UIを変更し、ホームプロバイダーで作成したメソッドを使用してデータを更新します.
結論
このアーキテクチャを用いることにより、UIを論理から非常によく分離することに成功した.すべてのコードを読みやすく編集する分離されます.
ソースコード
[ https://github.com/Marcusjnr/weather ]
Reference
この問題について(フラッターアーキテクチャ), 我々は、より多くの情報をここで見つけました
https://dev.to/marcusjnr/clean-code-flutter-3o3p
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
データフォルダでは、我々は2つのクラス
weather_data
and weather_repo
The
weather_data
class is responsible for fetching the weather data from the api, and returning the data to the repo class.
ThegetWeather
method takes in adio
parameter that will be parse in by the viewhome_screen
.
When the data has been gotten successfully from the api the weather class feeds the status of the response and the actual data to theOperation
class and returns an instance of this class to theWeather Repo
気象データ
import 'package:dio/dio.dart';
import 'package:weather_art/models/country_response_model.dart';
import 'package:weather_art/utils/operation.dart';
class WeatherData{
Future<Operation> getWeather(Dio dio) async{
try{
var response = await dio.get(
'http://api.openweathermap.org/data/2.5/weather?q=lagos&appid={api_key}',
).timeout(Duration(minutes: 2), onTimeout: () async{
return Response(
data: {"message": "Connection Timed out. Please try again"},
statusCode: 408);
}).catchError((error) {
return Response(
data: {"message": "Error occurred while connecting to server"},
statusCode: 508);
});
if(response.statusCode == 508 || response.statusCode == 408){
return Operation(response.statusCode, response.data);
}else{
WeatherResponse data = WeatherResponse.fromJson(response.data);
return Operation(response.statusCode, data);
}
}catch(err){
//catch err
}
}
}
}
final countryData = WeatherData();
The weather_repo
クラスはデータクラスを呼び出し、データを返すのを待つものです.天気予報
import 'package:dio/dio.dart';
import 'package:weather_art/data/weather_data.dart';
import 'package:weather_art/utils/operation.dart';
class _WeatherRepo{
getWeatherData(Dio dio, OperationCompleted countryDataCompleted){
countryData.getWeather(dio).then((data) => countryDataCompleted(data));
}
}
_WeatherRepo countryRepo = _WeatherRepo();
mixinクラス
mixinフォルダでは、1つのクラスを作成し、それを呼び出しますhome_helper
. このクラスは、プロバイダによって、取得したデータに応じてビューの状態を変更します.これは、状態を変更するためのコードがビュー自体から分離され、ビュー内で行われるロジックを減らすことを確認します
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:weather_art/data/weather_repo.dart';
import 'package:weather_art/models/country_response_model.dart';
import 'package:weather_art/providers/home_provider.dart';
import 'package:weather_art/utils/operation.dart';
mixin HomeHelper{
BuildContext _authContext;
doGetWeather(Dio dio, BuildContext context){
_authContext = context;
Provider.of<HomeProvider>(_authContext, listen: false).updateIsLoading(true);
weatherRepo.getWeatherData(dio, _weatherDataCompleted);
}
_weatherDataCompleted(Operation operation){
if(operation.code == 408 || operation.code == 508){
//handle time out
Provider.of<HomeProvider>(_authContext, listen: false).updateIsLoading(false);
print('connection timed out');
}else{
WeatherResponse weatherResponse = operation.result;
Provider.of<HomeProvider>(_authContext, listen: false).updateWeather(weatherResponse);
Provider.of<HomeProvider>(_authContext, listen: false).updateIsLoading(false);
}
}
}
モデルクラス
このフォルダで我々の天気モデルを作成します
// To parse this JSON data, do
//
// final weatherResponse = weatherResponseFromJson(jsonString);
import 'dart:convert';
WeatherResponse weatherResponseFromJson(String str) => WeatherResponse.fromJson(json.decode(str));
String weatherResponseToJson(WeatherResponse data) => json.encode(data.toJson());
class WeatherResponse {
WeatherResponse({
this.weather,
this.main,
});
List<Weather> weather;
Main main;
factory WeatherResponse.fromJson(Map<String, dynamic> json) => WeatherResponse(
coord: Coord.fromJson(json["coord"]),
weather: List<Weather>.from(json["weather"].map((x) => Weather.fromJson(x))),
main: Main.fromJson(json["main"]),
);
Map<String, dynamic> toJson() => {
"coord": coord.toJson(),
"weather": List<dynamic>.from(weather.map((x) => x.toJson())),
"main": main.toJson(),
};
}
class Main {
Main({
this.temp,
});
double temp;
factory Main.fromJson(Map<String, dynamic> json) => Main(
temp: json["temp"].toDouble(),
);
Map<String, dynamic> toJson() => {
"temp": temp,
};
}
class Weather {
Weather({
this.main,
this.description,
});
String main;
String description;
factory Weather.fromJson(Map<String, dynamic> json) => Weather(
main: json["main"],
description: json["description"],
);
Map<String, dynamic> toJson() => {
"main": main,
"description": description,
};
}
プロバイダーフォルダ
ここで2つのファイルを作成しますHomeProvider
and AppProvider
ホームプロバイダ
import 'package:flutter/foundation.dart';
import 'package:weather_art/models/country_response_model.dart';
class HomeProvider extends ChangeNotifier{
bool isLoading = false;
List<WeatherResponseModel> weatherList = [];
WeatherResponseModel weatherResponse;
void updateIsLoading(bool isLoadingGotten){
isLoading = isLoadingGotten;
notifyListeners();
}
void updateWeather(WeatherResponseModel weatherResponseGotten){
weatherResponse = weatherResponseGotten;
}
}
アプリプロバイダ
import 'package:dio/dio.dart';
class AppProvider{
Dio dio = Dio();
}
スクリーンフォルダ
これは私たちのビューがどこにあるか、ここでファイルを作成し、それを呼び出しますhome_screen
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:weather_art/mixin/home_helper.dart';
import 'package:weather_art/providers/app_provider.dart';
import 'package:weather_art/providers/home_provider.dart';
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> with HomeHelper{
@override
void initState() {
// TODO: implement initState
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
doGetWeather(
Provider.of<AppProvider>(context, listen: false).dio,
context
);
});
}
@override
Widget build(BuildContext context) {
return Consumer(
builder: (BuildContext context, HomeProvider homeProvider, Widget child){
return Scaffold(
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: decideLayout(homeProvider),
),
);
}
);
}
Widget decideLayout(HomeProvider homeProvider){
if(homeProvider.isLoading){
return Center(
child: CircularProgressIndicator(),
);
}else if(homeProvider.isLoading == false && homeProvider.weatherResponse == null){
return Center(
child: Text(
'Null',
style: TextStyle(
fontSize: 14
),
),
);
}else{
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Weather in Lagos',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold
),
),
Text(
'Looks Like ${homeProvider.weatherResponse.weather[0].main}',
style: TextStyle(
fontSize: 14
),
),
Text(
'Description ${homeProvider.weatherResponse.weather[0].description}',
style: TextStyle(
fontSize: 14
),
),
Text(
'Temp ${homeProvider.weatherResponse.main.temp.toString()}',
style: TextStyle(
fontSize: 14
),
),
],
);
}
}
}
Utilsフォルダ
このフォルダにはクラス操作が含まれます.あなたはちょうどあなたのコードでこれをコピーして、これを通り過ぎることができます.クラスは2つのparamsを受け入れます.レスポンスコードと応答データ.このクラスは、操作が完了したかどうかをチェックするために使用されるtypedefまたはコールバックです.
import 'package:flutter/material.dart';
typedef OperationCompleted(Operation operation);
class Operation {
final dynamic _result;
final int code;
Operation(this.code, this._result);
bool get succeeded => code >= 200 && code <= 226;
dynamic get result => _result;
}
流れ
私たちは、すべてのコードとクラスは、このパターンに関与して見てきました、それぞれのいくつかの説明で、今私は一緒にすべてを結合させ、アプリケーションとのユーザーの相互作用に従うことによって、1つの画像を描画し、各接続で何が起こるかを伝える.
ユーザーは彼が何をすべきかを探している彼の電話をクリックしています.そして、彼は「何が今日のようになるかについて天気です」と言います、そして、彼は我々のアプリを開けるために進みます.ユーザーは私達のhome_screen
, 我々home_screen
と呼ばれるmixinを使用しますHomeHelper
また、HomeProvider
それ自身の状態を管理する.
The isLoading
にHomeProvider
ユーザーが何かがロードされていることを示す循環的な進展を見るように、クラスはfalseです.これが起こっている間initState
呼び出しdoGetWeather
に必要なパラメータを指定します.The doGetWeather
ミックスからのHomeHelper
. The doGetWeather
呼び出しweatherRepo.getWeatherData
は_WeatherRepo
クラス.これはgetWeather
にWeatherData
クラスFuture
したがって、このメソッドは、何かをgetWeather
. getWeather
はAPIからデータを取得し、Operation
. Operation
ステータスコードとAPIからのデータである2つのパラメータを受け入れます.操作がgetWeather
, その後、データが後方に渡されます.
我々は、Repoクラスがまだ若干のデータを予想すると思い出すべきです.then
repoクラスを呼び出し、データをcountryDataCompleted
, これは順番に_weatherDataCompleted
インHomeHelper
. ここでは、UIを変更し、ホームプロバイダーで作成したメソッドを使用してデータを更新します.
結論
このアーキテクチャを用いることにより、UIを論理から非常によく分離することに成功した.すべてのコードを読みやすく編集する分離されます.
ソースコード
[ https://github.com/Marcusjnr/weather ]
Reference
この問題について(フラッターアーキテクチャ), 我々は、より多くの情報をここで見つけました
https://dev.to/marcusjnr/clean-code-flutter-3o3p
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:weather_art/data/weather_repo.dart';
import 'package:weather_art/models/country_response_model.dart';
import 'package:weather_art/providers/home_provider.dart';
import 'package:weather_art/utils/operation.dart';
mixin HomeHelper{
BuildContext _authContext;
doGetWeather(Dio dio, BuildContext context){
_authContext = context;
Provider.of<HomeProvider>(_authContext, listen: false).updateIsLoading(true);
weatherRepo.getWeatherData(dio, _weatherDataCompleted);
}
_weatherDataCompleted(Operation operation){
if(operation.code == 408 || operation.code == 508){
//handle time out
Provider.of<HomeProvider>(_authContext, listen: false).updateIsLoading(false);
print('connection timed out');
}else{
WeatherResponse weatherResponse = operation.result;
Provider.of<HomeProvider>(_authContext, listen: false).updateWeather(weatherResponse);
Provider.of<HomeProvider>(_authContext, listen: false).updateIsLoading(false);
}
}
}
このフォルダで我々の天気モデルを作成します
// To parse this JSON data, do
//
// final weatherResponse = weatherResponseFromJson(jsonString);
import 'dart:convert';
WeatherResponse weatherResponseFromJson(String str) => WeatherResponse.fromJson(json.decode(str));
String weatherResponseToJson(WeatherResponse data) => json.encode(data.toJson());
class WeatherResponse {
WeatherResponse({
this.weather,
this.main,
});
List<Weather> weather;
Main main;
factory WeatherResponse.fromJson(Map<String, dynamic> json) => WeatherResponse(
coord: Coord.fromJson(json["coord"]),
weather: List<Weather>.from(json["weather"].map((x) => Weather.fromJson(x))),
main: Main.fromJson(json["main"]),
);
Map<String, dynamic> toJson() => {
"coord": coord.toJson(),
"weather": List<dynamic>.from(weather.map((x) => x.toJson())),
"main": main.toJson(),
};
}
class Main {
Main({
this.temp,
});
double temp;
factory Main.fromJson(Map<String, dynamic> json) => Main(
temp: json["temp"].toDouble(),
);
Map<String, dynamic> toJson() => {
"temp": temp,
};
}
class Weather {
Weather({
this.main,
this.description,
});
String main;
String description;
factory Weather.fromJson(Map<String, dynamic> json) => Weather(
main: json["main"],
description: json["description"],
);
Map<String, dynamic> toJson() => {
"main": main,
"description": description,
};
}
プロバイダーフォルダ
ここで2つのファイルを作成しますHomeProvider
and AppProvider
ホームプロバイダ
import 'package:flutter/foundation.dart';
import 'package:weather_art/models/country_response_model.dart';
class HomeProvider extends ChangeNotifier{
bool isLoading = false;
List<WeatherResponseModel> weatherList = [];
WeatherResponseModel weatherResponse;
void updateIsLoading(bool isLoadingGotten){
isLoading = isLoadingGotten;
notifyListeners();
}
void updateWeather(WeatherResponseModel weatherResponseGotten){
weatherResponse = weatherResponseGotten;
}
}
アプリプロバイダ
import 'package:dio/dio.dart';
class AppProvider{
Dio dio = Dio();
}
スクリーンフォルダ
これは私たちのビューがどこにあるか、ここでファイルを作成し、それを呼び出しますhome_screen
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:weather_art/mixin/home_helper.dart';
import 'package:weather_art/providers/app_provider.dart';
import 'package:weather_art/providers/home_provider.dart';
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> with HomeHelper{
@override
void initState() {
// TODO: implement initState
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
doGetWeather(
Provider.of<AppProvider>(context, listen: false).dio,
context
);
});
}
@override
Widget build(BuildContext context) {
return Consumer(
builder: (BuildContext context, HomeProvider homeProvider, Widget child){
return Scaffold(
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: decideLayout(homeProvider),
),
);
}
);
}
Widget decideLayout(HomeProvider homeProvider){
if(homeProvider.isLoading){
return Center(
child: CircularProgressIndicator(),
);
}else if(homeProvider.isLoading == false && homeProvider.weatherResponse == null){
return Center(
child: Text(
'Null',
style: TextStyle(
fontSize: 14
),
),
);
}else{
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Weather in Lagos',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold
),
),
Text(
'Looks Like ${homeProvider.weatherResponse.weather[0].main}',
style: TextStyle(
fontSize: 14
),
),
Text(
'Description ${homeProvider.weatherResponse.weather[0].description}',
style: TextStyle(
fontSize: 14
),
),
Text(
'Temp ${homeProvider.weatherResponse.main.temp.toString()}',
style: TextStyle(
fontSize: 14
),
),
],
);
}
}
}
Utilsフォルダ
このフォルダにはクラス操作が含まれます.あなたはちょうどあなたのコードでこれをコピーして、これを通り過ぎることができます.クラスは2つのparamsを受け入れます.レスポンスコードと応答データ.このクラスは、操作が完了したかどうかをチェックするために使用されるtypedefまたはコールバックです.
import 'package:flutter/material.dart';
typedef OperationCompleted(Operation operation);
class Operation {
final dynamic _result;
final int code;
Operation(this.code, this._result);
bool get succeeded => code >= 200 && code <= 226;
dynamic get result => _result;
}
流れ
私たちは、すべてのコードとクラスは、このパターンに関与して見てきました、それぞれのいくつかの説明で、今私は一緒にすべてを結合させ、アプリケーションとのユーザーの相互作用に従うことによって、1つの画像を描画し、各接続で何が起こるかを伝える.
ユーザーは彼が何をすべきかを探している彼の電話をクリックしています.そして、彼は「何が今日のようになるかについて天気です」と言います、そして、彼は我々のアプリを開けるために進みます.ユーザーは私達のhome_screen
, 我々home_screen
と呼ばれるmixinを使用しますHomeHelper
また、HomeProvider
それ自身の状態を管理する.
The isLoading
にHomeProvider
ユーザーが何かがロードされていることを示す循環的な進展を見るように、クラスはfalseです.これが起こっている間initState
呼び出しdoGetWeather
に必要なパラメータを指定します.The doGetWeather
ミックスからのHomeHelper
. The doGetWeather
呼び出しweatherRepo.getWeatherData
は_WeatherRepo
クラス.これはgetWeather
にWeatherData
クラスFuture
したがって、このメソッドは、何かをgetWeather
. getWeather
はAPIからデータを取得し、Operation
. Operation
ステータスコードとAPIからのデータである2つのパラメータを受け入れます.操作がgetWeather
, その後、データが後方に渡されます.
我々は、Repoクラスがまだ若干のデータを予想すると思い出すべきです.then
repoクラスを呼び出し、データをcountryDataCompleted
, これは順番に_weatherDataCompleted
インHomeHelper
. ここでは、UIを変更し、ホームプロバイダーで作成したメソッドを使用してデータを更新します.
結論
このアーキテクチャを用いることにより、UIを論理から非常によく分離することに成功した.すべてのコードを読みやすく編集する分離されます.
ソースコード
[ https://github.com/Marcusjnr/weather ]
Reference
この問題について(フラッターアーキテクチャ), 我々は、より多くの情報をここで見つけました
https://dev.to/marcusjnr/clean-code-flutter-3o3p
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
import 'package:flutter/foundation.dart';
import 'package:weather_art/models/country_response_model.dart';
class HomeProvider extends ChangeNotifier{
bool isLoading = false;
List<WeatherResponseModel> weatherList = [];
WeatherResponseModel weatherResponse;
void updateIsLoading(bool isLoadingGotten){
isLoading = isLoadingGotten;
notifyListeners();
}
void updateWeather(WeatherResponseModel weatherResponseGotten){
weatherResponse = weatherResponseGotten;
}
}
import 'package:dio/dio.dart';
class AppProvider{
Dio dio = Dio();
}
これは私たちのビューがどこにあるか、ここでファイルを作成し、それを呼び出します
home_screen
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:weather_art/mixin/home_helper.dart';
import 'package:weather_art/providers/app_provider.dart';
import 'package:weather_art/providers/home_provider.dart';
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> with HomeHelper{
@override
void initState() {
// TODO: implement initState
super.initState();
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
doGetWeather(
Provider.of<AppProvider>(context, listen: false).dio,
context
);
});
}
@override
Widget build(BuildContext context) {
return Consumer(
builder: (BuildContext context, HomeProvider homeProvider, Widget child){
return Scaffold(
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: decideLayout(homeProvider),
),
);
}
);
}
Widget decideLayout(HomeProvider homeProvider){
if(homeProvider.isLoading){
return Center(
child: CircularProgressIndicator(),
);
}else if(homeProvider.isLoading == false && homeProvider.weatherResponse == null){
return Center(
child: Text(
'Null',
style: TextStyle(
fontSize: 14
),
),
);
}else{
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Weather in Lagos',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold
),
),
Text(
'Looks Like ${homeProvider.weatherResponse.weather[0].main}',
style: TextStyle(
fontSize: 14
),
),
Text(
'Description ${homeProvider.weatherResponse.weather[0].description}',
style: TextStyle(
fontSize: 14
),
),
Text(
'Temp ${homeProvider.weatherResponse.main.temp.toString()}',
style: TextStyle(
fontSize: 14
),
),
],
);
}
}
}
Utilsフォルダ
このフォルダにはクラス操作が含まれます.あなたはちょうどあなたのコードでこれをコピーして、これを通り過ぎることができます.クラスは2つのparamsを受け入れます.レスポンスコードと応答データ.このクラスは、操作が完了したかどうかをチェックするために使用されるtypedefまたはコールバックです.
import 'package:flutter/material.dart';
typedef OperationCompleted(Operation operation);
class Operation {
final dynamic _result;
final int code;
Operation(this.code, this._result);
bool get succeeded => code >= 200 && code <= 226;
dynamic get result => _result;
}
流れ
私たちは、すべてのコードとクラスは、このパターンに関与して見てきました、それぞれのいくつかの説明で、今私は一緒にすべてを結合させ、アプリケーションとのユーザーの相互作用に従うことによって、1つの画像を描画し、各接続で何が起こるかを伝える.
ユーザーは彼が何をすべきかを探している彼の電話をクリックしています.そして、彼は「何が今日のようになるかについて天気です」と言います、そして、彼は我々のアプリを開けるために進みます.ユーザーは私達のhome_screen
, 我々home_screen
と呼ばれるmixinを使用しますHomeHelper
また、HomeProvider
それ自身の状態を管理する.
The isLoading
にHomeProvider
ユーザーが何かがロードされていることを示す循環的な進展を見るように、クラスはfalseです.これが起こっている間initState
呼び出しdoGetWeather
に必要なパラメータを指定します.The doGetWeather
ミックスからのHomeHelper
. The doGetWeather
呼び出しweatherRepo.getWeatherData
は_WeatherRepo
クラス.これはgetWeather
にWeatherData
クラスFuture
したがって、このメソッドは、何かをgetWeather
. getWeather
はAPIからデータを取得し、Operation
. Operation
ステータスコードとAPIからのデータである2つのパラメータを受け入れます.操作がgetWeather
, その後、データが後方に渡されます.
我々は、Repoクラスがまだ若干のデータを予想すると思い出すべきです.then
repoクラスを呼び出し、データをcountryDataCompleted
, これは順番に_weatherDataCompleted
インHomeHelper
. ここでは、UIを変更し、ホームプロバイダーで作成したメソッドを使用してデータを更新します.
結論
このアーキテクチャを用いることにより、UIを論理から非常によく分離することに成功した.すべてのコードを読みやすく編集する分離されます.
ソースコード
[ https://github.com/Marcusjnr/weather ]
Reference
この問題について(フラッターアーキテクチャ), 我々は、より多くの情報をここで見つけました
https://dev.to/marcusjnr/clean-code-flutter-3o3p
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
import 'package:flutter/material.dart';
typedef OperationCompleted(Operation operation);
class Operation {
final dynamic _result;
final int code;
Operation(this.code, this._result);
bool get succeeded => code >= 200 && code <= 226;
dynamic get result => _result;
}
私たちは、すべてのコードとクラスは、このパターンに関与して見てきました、それぞれのいくつかの説明で、今私は一緒にすべてを結合させ、アプリケーションとのユーザーの相互作用に従うことによって、1つの画像を描画し、各接続で何が起こるかを伝える.
ユーザーは彼が何をすべきかを探している彼の電話をクリックしています.そして、彼は「何が今日のようになるかについて天気です」と言います、そして、彼は我々のアプリを開けるために進みます.ユーザーは私達の
home_screen
, 我々home_screen
と呼ばれるmixinを使用しますHomeHelper
また、HomeProvider
それ自身の状態を管理する.The
isLoading
にHomeProvider
ユーザーが何かがロードされていることを示す循環的な進展を見るように、クラスはfalseです.これが起こっている間initState
呼び出しdoGetWeather
に必要なパラメータを指定します.The doGetWeather
ミックスからのHomeHelper
. The doGetWeather
呼び出しweatherRepo.getWeatherData
は_WeatherRepo
クラス.これはgetWeather
にWeatherData
クラスFuture
したがって、このメソッドは、何かをgetWeather
. getWeather
はAPIからデータを取得し、Operation
. Operation
ステータスコードとAPIからのデータである2つのパラメータを受け入れます.操作がgetWeather
, その後、データが後方に渡されます.我々は、Repoクラスがまだ若干のデータを予想すると思い出すべきです
.then
repoクラスを呼び出し、データをcountryDataCompleted
, これは順番に_weatherDataCompleted
インHomeHelper
. ここでは、UIを変更し、ホームプロバイダーで作成したメソッドを使用してデータを更新します.結論
このアーキテクチャを用いることにより、UIを論理から非常によく分離することに成功した.すべてのコードを読みやすく編集する分離されます.
ソースコード
[ https://github.com/Marcusjnr/weather ]
Reference
この問題について(フラッターアーキテクチャ), 我々は、より多くの情報をここで見つけました
https://dev.to/marcusjnr/clean-code-flutter-3o3p
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
Reference
この問題について(フラッターアーキテクチャ), 我々は、より多くの情報をここで見つけました https://dev.to/marcusjnr/clean-code-flutter-3o3pテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol