진동 구조
본고에서 저는 당신에게 코드를 깔끔하게 하는 방법을 보여 드리겠습니다. 물론 이런 구조는 유연하기 때문에 당신은 그것을 변경하거나 편집할 수 있습니다.관심사의 분리를 고려한 것이다.
뭐 공부 해요?
일을 매우 간단하게 하기 위해서, Openweathermapapi를 사용하여 날씨 데이터를 가져오고, 그 중 일부 데이터를 텍스트로 화면에 표시합니다.최종 응용은 다음과 같다.
프로젝트 설정
이 항목은 우리lib 디렉터리에 모두 6개의 폴더가 있습니다
이 항목은 우리lib 디렉터리에 모두 6개의 폴더가 있습니다
공급자 [https://pub.dev/packages/provider]
Dio[https://pub.dev/packages/dio]
프로세스
우리의 응용 프로그램 흐름은 서로 다른 종류로 나뉘어 있으며, 각 종류는 특정한 임무를 수행한다.
나는 코드를 보여주고 이 종류의 기능을 설명할 것이다. 마지막으로, 나는 전체 과정을 상세하게 설명할 것이다.
데이터 클래스
데이터 폴더에서 클래스 2개 weather_data
및 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();
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 폴더에서 클래스를 만들고 이름을 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,
};
}
공급자 폴더
우리는 이곳에서 두 개의 파일 HomeProvider
과 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();
}
Screens 폴더
이것이 바로 우리의 보기가 있는 위치입니다. 여기서 파일을 만들고 이름을 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 폴더
이 폴더에는 클래스 작업이 포함되어 있습니다.코드에서 복사해서 통과하기만 하면 됩니다.이 클래스는 두 개의 매개 변수를 받아들인다.응답 코드와 응답 데이터.이것은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;
}
흐르다
우리는 이미 이 모델에 관련된 모든 코드와 클래스를 보았고 모든 코드와 클래스에 대해 설명을 했습니다. 지금은 모든 코드와 클래스를 연결시켜 사용자와 응용 프로그램의 상호작용을 추적하고 연결점마다 무슨 일이 일어났는지 알려 줍니다.
한 사용자가 그의 핸드폰 주위를 클릭하여 무엇을 해야 할지 찾은 후에 "오늘 날씨가 어떻게 될지"라고 말했다. 그리고 그는 계속해서 우리의 앱을 열었다.사용자는 우리home_screen
를 보게 될 것이며, 우리home_screen
는 우리HomeHelper
라고 불리는mixin을 사용하고, HomeProvider
를 사용하여 자신의 상태를 관리할 것이다.isLoading
클래스의 HomeProvider
은false이기 때문에 사용자는 순환 진도를 보고 어떤 내용을 불러오고 있음을 표시합니다.이 경우 initState
필요한 매개 변수 호출doGetWeather
을 사용합니다.doGetWeather
mixinHomeHelper
에서 왔다.doGetWeather
류에서 온 weatherRepo.getWeatherData
을 호출합니다.이것은 _WeatherRepo
클래스 중의 getWeather
을 호출할 것입니다. 이 클래스는 WeatherData
이기 때문에 이 방법은 Future
에서 일부 내용을 되돌려 주기를 기대합니다.getWeather
api에서 데이터를 가져와 되돌려줍니다getWeather
.Operation
두 개의 매개 변수, 즉 상태 코드와api에서 온 데이터를 받아들인다.작업이 Operation
에서 반환되면 데이터는 뒤로 전달됩니다.
리포클래스는 리포클래스 getWeather
로 되돌아와 .then
로 데이터를 전달할 때 countryDataCompleted
의 _weatherDataCompleted
를 촉발할 수 있다는 것을 기억해야 한다.이것이 바로 우리가 Home Provider에서 만든 방법으로 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
및 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();
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 폴더에서 클래스를 만들고 이름을 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,
};
}
공급자 폴더
우리는 이곳에서 두 개의 파일 HomeProvider
과 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();
}
Screens 폴더
이것이 바로 우리의 보기가 있는 위치입니다. 여기서 파일을 만들고 이름을 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 폴더
이 폴더에는 클래스 작업이 포함되어 있습니다.코드에서 복사해서 통과하기만 하면 됩니다.이 클래스는 두 개의 매개 변수를 받아들인다.응답 코드와 응답 데이터.이것은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;
}
흐르다
우리는 이미 이 모델에 관련된 모든 코드와 클래스를 보았고 모든 코드와 클래스에 대해 설명을 했습니다. 지금은 모든 코드와 클래스를 연결시켜 사용자와 응용 프로그램의 상호작용을 추적하고 연결점마다 무슨 일이 일어났는지 알려 줍니다.
한 사용자가 그의 핸드폰 주위를 클릭하여 무엇을 해야 할지 찾은 후에 "오늘 날씨가 어떻게 될지"라고 말했다. 그리고 그는 계속해서 우리의 앱을 열었다.사용자는 우리home_screen
를 보게 될 것이며, 우리home_screen
는 우리HomeHelper
라고 불리는mixin을 사용하고, HomeProvider
를 사용하여 자신의 상태를 관리할 것이다.isLoading
클래스의 HomeProvider
은false이기 때문에 사용자는 순환 진도를 보고 어떤 내용을 불러오고 있음을 표시합니다.이 경우 initState
필요한 매개 변수 호출doGetWeather
을 사용합니다.doGetWeather
mixinHomeHelper
에서 왔다.doGetWeather
류에서 온 weatherRepo.getWeatherData
을 호출합니다.이것은 _WeatherRepo
클래스 중의 getWeather
을 호출할 것입니다. 이 클래스는 WeatherData
이기 때문에 이 방법은 Future
에서 일부 내용을 되돌려 주기를 기대합니다.getWeather
api에서 데이터를 가져와 되돌려줍니다getWeather
.Operation
두 개의 매개 변수, 즉 상태 코드와api에서 온 데이터를 받아들인다.작업이 Operation
에서 반환되면 데이터는 뒤로 전달됩니다.
리포클래스는 리포클래스 getWeather
로 되돌아와 .then
로 데이터를 전달할 때 countryDataCompleted
의 _weatherDataCompleted
를 촉발할 수 있다는 것을 기억해야 한다.이것이 바로 우리가 Home Provider에서 만든 방법으로 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,
};
}
공급자 폴더
우리는 이곳에서 두 개의 파일 HomeProvider
과 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();
}
Screens 폴더
이것이 바로 우리의 보기가 있는 위치입니다. 여기서 파일을 만들고 이름을 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 폴더
이 폴더에는 클래스 작업이 포함되어 있습니다.코드에서 복사해서 통과하기만 하면 됩니다.이 클래스는 두 개의 매개 변수를 받아들인다.응답 코드와 응답 데이터.이것은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;
}
흐르다
우리는 이미 이 모델에 관련된 모든 코드와 클래스를 보았고 모든 코드와 클래스에 대해 설명을 했습니다. 지금은 모든 코드와 클래스를 연결시켜 사용자와 응용 프로그램의 상호작용을 추적하고 연결점마다 무슨 일이 일어났는지 알려 줍니다.
한 사용자가 그의 핸드폰 주위를 클릭하여 무엇을 해야 할지 찾은 후에 "오늘 날씨가 어떻게 될지"라고 말했다. 그리고 그는 계속해서 우리의 앱을 열었다.사용자는 우리home_screen
를 보게 될 것이며, 우리home_screen
는 우리HomeHelper
라고 불리는mixin을 사용하고, HomeProvider
를 사용하여 자신의 상태를 관리할 것이다.isLoading
클래스의 HomeProvider
은false이기 때문에 사용자는 순환 진도를 보고 어떤 내용을 불러오고 있음을 표시합니다.이 경우 initState
필요한 매개 변수 호출doGetWeather
을 사용합니다.doGetWeather
mixinHomeHelper
에서 왔다.doGetWeather
류에서 온 weatherRepo.getWeatherData
을 호출합니다.이것은 _WeatherRepo
클래스 중의 getWeather
을 호출할 것입니다. 이 클래스는 WeatherData
이기 때문에 이 방법은 Future
에서 일부 내용을 되돌려 주기를 기대합니다.getWeather
api에서 데이터를 가져와 되돌려줍니다getWeather
.Operation
두 개의 매개 변수, 즉 상태 코드와api에서 온 데이터를 받아들인다.작업이 Operation
에서 반환되면 데이터는 뒤로 전달됩니다.
리포클래스는 리포클래스 getWeather
로 되돌아와 .then
로 데이터를 전달할 때 countryDataCompleted
의 _weatherDataCompleted
를 촉발할 수 있다는 것을 기억해야 한다.이것이 바로 우리가 Home Provider에서 만든 방법으로 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 폴더
이 폴더에는 클래스 작업이 포함되어 있습니다.코드에서 복사해서 통과하기만 하면 됩니다.이 클래스는 두 개의 매개 변수를 받아들인다.응답 코드와 응답 데이터.이것은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;
}
흐르다
우리는 이미 이 모델에 관련된 모든 코드와 클래스를 보았고 모든 코드와 클래스에 대해 설명을 했습니다. 지금은 모든 코드와 클래스를 연결시켜 사용자와 응용 프로그램의 상호작용을 추적하고 연결점마다 무슨 일이 일어났는지 알려 줍니다.
한 사용자가 그의 핸드폰 주위를 클릭하여 무엇을 해야 할지 찾은 후에 "오늘 날씨가 어떻게 될지"라고 말했다. 그리고 그는 계속해서 우리의 앱을 열었다.사용자는 우리home_screen
를 보게 될 것이며, 우리home_screen
는 우리HomeHelper
라고 불리는mixin을 사용하고, HomeProvider
를 사용하여 자신의 상태를 관리할 것이다.isLoading
클래스의 HomeProvider
은false이기 때문에 사용자는 순환 진도를 보고 어떤 내용을 불러오고 있음을 표시합니다.이 경우 initState
필요한 매개 변수 호출doGetWeather
을 사용합니다.doGetWeather
mixinHomeHelper
에서 왔다.doGetWeather
류에서 온 weatherRepo.getWeatherData
을 호출합니다.이것은 _WeatherRepo
클래스 중의 getWeather
을 호출할 것입니다. 이 클래스는 WeatherData
이기 때문에 이 방법은 Future
에서 일부 내용을 되돌려 주기를 기대합니다.getWeather
api에서 데이터를 가져와 되돌려줍니다getWeather
.Operation
두 개의 매개 변수, 즉 상태 코드와api에서 온 데이터를 받아들인다.작업이 Operation
에서 반환되면 데이터는 뒤로 전달됩니다.
리포클래스는 리포클래스 getWeather
로 되돌아와 .then
로 데이터를 전달할 때 countryDataCompleted
의 _weatherDataCompleted
를 촉발할 수 있다는 것을 기억해야 한다.이것이 바로 우리가 Home Provider에서 만든 방법으로 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;
}
우리는 이미 이 모델에 관련된 모든 코드와 클래스를 보았고 모든 코드와 클래스에 대해 설명을 했습니다. 지금은 모든 코드와 클래스를 연결시켜 사용자와 응용 프로그램의 상호작용을 추적하고 연결점마다 무슨 일이 일어났는지 알려 줍니다.
한 사용자가 그의 핸드폰 주위를 클릭하여 무엇을 해야 할지 찾은 후에 "오늘 날씨가 어떻게 될지"라고 말했다. 그리고 그는 계속해서 우리의 앱을 열었다.사용자는 우리
home_screen
를 보게 될 것이며, 우리home_screen
는 우리HomeHelper
라고 불리는mixin을 사용하고, HomeProvider
를 사용하여 자신의 상태를 관리할 것이다.isLoading
클래스의 HomeProvider
은false이기 때문에 사용자는 순환 진도를 보고 어떤 내용을 불러오고 있음을 표시합니다.이 경우 initState
필요한 매개 변수 호출doGetWeather
을 사용합니다.doGetWeather
mixinHomeHelper
에서 왔다.doGetWeather
류에서 온 weatherRepo.getWeatherData
을 호출합니다.이것은 _WeatherRepo
클래스 중의 getWeather
을 호출할 것입니다. 이 클래스는 WeatherData
이기 때문에 이 방법은 Future
에서 일부 내용을 되돌려 주기를 기대합니다.getWeather
api에서 데이터를 가져와 되돌려줍니다getWeather
.Operation
두 개의 매개 변수, 즉 상태 코드와api에서 온 데이터를 받아들인다.작업이 Operation
에서 반환되면 데이터는 뒤로 전달됩니다.리포클래스는 리포클래스
getWeather
로 되돌아와 .then
로 데이터를 전달할 때 countryDataCompleted
의 _weatherDataCompleted
를 촉발할 수 있다는 것을 기억해야 한다.이것이 바로 우리가 Home Provider에서 만든 방법으로 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.)