preface
In previous articles, we covered the basics of GetX, including state management, route management, dependency management, internationalization, and so on.
Today we will use a small case to make a summary based on the knowledge learned before. This case is mainly about network data request, model processing and GetXController, which is implemented by MVC model.
Video Tutorial Address
Zero basic video tutorial address
Requesting network data
Dart is used to request network data, which is data from a news list.
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter_getx_example/GetXApiDataExample/MovieModule/Models/MovieModel.dart';
class ApiService {
static Future<List<MovieModel>> fetchMovie() async {
var response = await Dio().get("http://apis.juhe.cn/fapig/douyin/billboard?type=hot_video&size=50&key=9eb8ac7020d9bea6048db1f4c6b6d028");
if (response.statusCode == 200) {
var jsonString = response.data['result'];
return movieModelFromJson(json.encode(response.data["result"])); }}}Copy the code
Defining model classes
Dart is used for model transformation of the data requested from the network.
// To parse this JSON data, do
//
// final movieModel = movieModelFromJson(jsonString);
import 'dart:convert';
List<MovieModel> movieModelFromJson(String str) => List<MovieModel>.from(json.decode(str).map((x) => MovieModel.fromJson(x)));
String movieModelToJson(List<MovieModel> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class MovieModel {
MovieModel({
this.title,
this.shareUrl,
this.author,
this.itemCover,
this.hotValue,
this.hotWords,
this.playCount,
this.diggCount,
this.commentCount,
});
String title;
String shareUrl;
String author;
String itemCover;
int hotValue;
String hotWords;
int playCount;
int diggCount;
int commentCount;
factory MovieModel.fromJson(Map<String.dynamic> json) => MovieModel(
title: json["title"],
shareUrl: json["share_url"],
author: json["author"],
itemCover: json["item_cover"],
hotValue: json["hot_value"],
hotWords: json["hot_words"],
playCount: json["play_count"],
diggCount: json["digg_count"],
commentCount: json["comment_count"]);Map<String.dynamic> toJson() => {
"title": title,
"share_url": shareUrl,
"author": author,
"item_cover": itemCover,
"hot_value": hotValue,
"hot_words": hotWords,
"play_count": playCount,
"digg_count": diggCount,
"comment_count": commentCount,
};
}
Copy the code
Data is processed using a controller
We convert the requested network data into Model and add a loading before the request. When the network data request comes back, the loading is disabled. Let’s take a look at the code
import 'package:flutter_getx_example/GetXApiDataExample/ApiModule/ApiService.dart';
import 'package:flutter_getx_example/GetXApiDataExample/MovieModule/Models/MovieModel.dart';
import 'package:get/get.dart';
class MovieController extends GetxController {
var isLoading = true.obs;
// ignore: deprecated_member_use
var movieList = List<MovieModel>().obs;
@override
void onInit() {
// TODO: implement onInit
fetchMovie();
super.onInit();
}
void fetchMovie() async {
try {
isLoading(true);
var movie = await ApiService.fetchMovie();
if(movie ! =null) { movieList.assignAll(movie); }}finally {
isLoading(false); }}}Copy the code
Display list data at the view layer
We’ve dealt with the network request, the model, and the data processing. Our final goal is to display the data on the page, so let’s look at the view code
import 'package:flutter/material.dart';
import 'package:flutter_getx_example/GetXApiDataExample/MovieModule/Controller/MovieController.dart';
import 'package:get/get.dart';
class MovieListView extends StatelessWidget {
final MovieController movieController = Get.put(MovieController());
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Movie"),
),
body: Obx(() {
if (movieController.isLoading.value) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return ListView.builder(
itemCount: movieController.movieList.length,
itemBuilder: (context, index) {
return Column(
children: [
Row(
children: [
Container(
width: 100,
height: 120,
margin: EdgeInsets.all(10),
child: ClipRRect(
borderRadius: BorderRadius.circular(6),
child: Image.network(
movieController.movieList[index].itemCover,
width: 150,
height: 100,
fit: BoxFit.fill,
// color: Colors.orange,
// colorBlendMode: BlendMode.color,
),
),
),
Flexible(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
movieController.movieList[index].author,
style: TextStyle(
color: Colors.black45,
fontSize: 16
),
)
],
),
),
],
),
Container(
color: Colors.grey.shade300,
height: 2,),); }); }})); }Copy the code
Results show
conclusion
The most important thing in this case is to separate the UI from the business logic by inheriting from GetxController, instantiating the controller via Get. Put, and then performing a state refresh of the data using Obx.