美文网首页Flutter
GetX系列教程---新闻案例

GetX系列教程---新闻案例

作者: Jimi | 来源:发表于2021-09-14 10:07 被阅读0次

    前言

    在前面的文章中我们对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

    总结

    该案例中最重要的通过继承自GetxController分离了UI业务逻辑,并通过Get.put对控制器进行了实例化,然后使用Obx对数据进行了一个状态刷新。

    相关文章

      网友评论

        本文标题:GetX系列教程---新闻案例

        本文链接:https://www.haomeiwen.com/subject/edqcgltx.html