14.4.flutter_GetX

2022-01-27  本文已影响0人  ChaosHeart

前言

在前面的文章中我们对GetX的基础知识进行了讲解,包括状态管理路由管理依赖管理国际化等。

今天我们来将一个小案例用于结合前面学习的知识做一个总结,这个案例主要是讲解网络数据请求模型处理GetXController,用MVC模型来实现。

视频教程地址

零基础视频教程地址

请求网络数据

我们新建一个ApiService.dart用于请求网络数据,该数据是一个新闻列表的数据。

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"]));
    }
  }

}

定义模型类

我们新建一个MovieModel.dart用来对网络请求回来的数据进行模型转换。

// 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,
 };
}

使用控制器对数据进行处理

我们对请求回来的网络数据转化为Model,并在请求前增加一个loading,当网络数据请求回来的时候关闭loading,我们来看一下代码

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);
    }
  }
}

在视图层展示列表数据

前面我们对网络请求、模型、数据处理进行了处理,我们最终的目的是需要把数据展示到页面上,那我们接着来看一下视图的代码

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,
                 )
               ],
             );
           },
         );
       }
     }),
   );
 }

效果展示

image

参考:

https://liujunmin.com/flutter/getx/getx_news.html

上一篇 下一篇

猜你喜欢

热点阅读