24일차 과제 - rlatkddbs99/Flutter GitHub Wiki

json 활용하기. 좀 많이 봐야 될듯;; Android Emulator - flutter_emulator_5554 2023-02-27 14-46-09

main.dart

import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:serial/pages/mainPage.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: mainPage(),
    );
  }
}

pages폴더의 mainPage.dart

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:serial/model/dog.dart';
import 'package:serial/widget/dog_detail.dart';

class mainPage extends StatelessWidget {
  const mainPage({super.key});

  Future<Dog?> getData() async {
    var url = "https://dog.ceo/api/breeds/image/random";
    Dio dio = Dio();
    var res = await dio.get(url);
    if (res.statusCode == 200) {
      return Dog.fromMap(res.data);
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GridView.builder(
        //갤러리 형태로, 계속 무한 생성위해
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3, crossAxisSpacing: 4, mainAxisSpacing: 4),
        itemBuilder: ((context, index) {
          return FutureBuilder(
            future: getData(),
            builder: ((context, snapshot) {
              if (snapshot.hasData) {
                return snapshot.data?.message == null
                    ? //image에는 스트링값이 들어가야 해서 삼항연산자로 체크
                    SizedBox()
                    : GestureDetector(
                        onTap: () {
                          //눌렀을 때 이벤트
                          showDialog(
                              context: context,
                              builder: (context) => dog_detail(
                                  dog: snapshot
                                      .data!)); //builder에는 그냥 context쓰고 뭘 표현할지 지금은 dog_detail을 custom widget으로 만들어서 넘김. 근데
                          //넘겨줄 때 Dog를 넘겨주기로 했으니까 매개변수 필요, 선택한 강아지의 데이터가 넘어감. override로 toString재정의 해서 message값만 넘어감
                        },
                        child: Image.network(
                          snapshot.data!.message,
                          fit: BoxFit.fill,
                        ),
                      );
              }
              return CircularProgressIndicator();
            }),
          );
        }),
      ),
    );
  }
}

클래스생성하는 model폴더의 dog.dart

class Dog {
  String message;
  String status;

  Dog({required this.message, required this.status});

  factory Dog.fromMap(Map<String, dynamic> map) {
    return Dog(message: map['message'], status: map['status']);
  }

  @override
  String toString() {
    return message;
  }
}

Custom Widget인 widget폴더의 dog_detail.dart

import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/container.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:serial/model/dog.dart';

class dog_detail extends StatelessWidget {
  const dog_detail({super.key, required this.dog});
  final Dog dog; //이미지url을 받아서 표현하려고 Dog클래스 자체를 받아옴
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Card(
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
        clipBehavior: Clip.antiAlias, //image크기가 너무 클때 자름
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Image.network(
                dog.message), //이미지 표현. dog로 넘겨줬으니 dog로 받고 .message로 접근
            TextButton(
                //닫기버튼
                onPressed: () {
                  Navigator.pop(context);
                },
                child: Text("close"))
          ],
        ),
      ),
    );
  }
}
⚠️ **GitHub.com Fallback** ⚠️