Flutter 공부 5일차

devkwon·2023년 1월 31일
0

도서 리스트 프로젝트

BookRepository

import '../models/book.dart';

class BookRepository{
  final List<Book> _dummyBooks = [
    Book(
      title:'패키지 없이 R로 구현하는 심층 강화학습',
      subtitle: '손으로 풀어보는 Q-Learning부터 R로 구현하는 심층 강화학습까지',
      description: "머신러닝과 강화학습의 기본 개념부터 심층 강화학습의 알고리즘과 발전방향까지! "
          "본 서는 강화학습의 기본 요소와 작동 원리에 대해 상세히 다루는데, 딥러닝 프레임 워크를 사용하는 것이 아닌, R base code로 강화학습을 구현하여 "
          "강화학습 작동원리를 이해한다. Atari 게임 환경 외에 실생활에서 강화학습을 적용하고자 하는 독자들을 위하여 환경을 직접 설계함과 동시에 패키지 "
          "없이 low level부터 모든 것을 구현하기 때문에, 이 책을 통해 강화학습의 이론적 내용을 이해하고 알고리즘 및 환경을 구현하는 능력을 함양하여, "
          "풀고자 하는 다양한 상황에서 쉽게 활용할 수 있을 것이다.  ",
      image: 'https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCuoqW%2Fbtq8uatukHu%2FO0VapTwcTTpV3T29lqMYd0%2Fimg.png',
    ),
    Book(
      title:'바로 찾아 바로 만드는 포토샵 콘텐츠 디자인 북',
      subtitle: '발등에 불 떨어진 마케터, 기획자 모두 모여라! ',
      description: '바로 찾아 바로 만드는 포토샵 콘텐츠 디자인 북! 일명, \“바.바.북!\”'
      '지금까지 이런 포토샵 도서는 없었다!',
      image: 'https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Flzlyb%2Fbtq8nD5gYAf%2FiuHnWoFZPoBM35Y89aQZb0%2Fimg.png',
    )
  ];
  List<Book> getBooks(){
    return _dummyBooks;
  }
}

Models

class Book{
  final String title;
  final String subtitle;
  final String description;
  final String image;

  Book({
    required this.title,
    required this.subtitle,
    required this.description,
    required this.image,
});
}

Screens

detail_screen

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../models/book.dart';

class DetailScreen extends StatelessWidget{
  final Book book;
  DetailScreen({required this.book});
  @override
  Widget build(BuildContext context){
    return Scaffold(
      appBar: AppBar(
        title: Text('책 설명'),
      ),
      body: Column(
        children: [
          Image.network(book.image),
          Padding(padding: EdgeInsets.all(3)),
          Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Container(
                width: MediaQuery.of(context).size.width*0.8,
                padding: EdgeInsets.all(10),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Container(
                      child: Text(book.title,
                      style: TextStyle(
                        fontSize: 23,
                        fontWeight: FontWeight.bold,
                      ),),
                    ),
                    Text(book.subtitle, style: TextStyle(fontSize: 18, color:Colors.grey),)
                  ],
                ),
              ),
              Container(
                width: MediaQuery.of(context).size.width*0.15,
                padding: EdgeInsets.all(10),
                child: Center(
                  child: Icon(
                    Icons.star,
                    color: Colors.red,
                  ),
                ),
              )
            ],
          ),
          Padding(padding: EdgeInsets.all(3)),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              Column(
                children: [
                  Icon(
                    Icons.call,
                    color: Colors.blue,
                  ),
                  Text(
                    'Contact',
                    style: TextStyle(color:Colors.blue)
                  )
                ],
              ),
              Column(
                children: [
                  Icon(Icons.near_me, color: Colors.blue,),
                  Text('Route', style:TextStyle(color: Colors.blue))
                ],
              ),
              Column(
                children: [
                  Icon(Icons.save, color: Colors.blue,),
                  Text('Save', style:TextStyle(color: Colors.blue))
                ],
              ),
            ],
          ),
          Container(
            padding: EdgeInsets.all(15),
            child: Text(
              book.description
            ),
          )
        ],
        ),
    );
  }
}

list_screen

import 'package:flutter/material.dart';

import '../BookRepository/book_repository.dart';
import '../models/book.dart';
import 'detail_screen.dart';

class ListScreen extends StatelessWidget{
  final List<Book> books = BookRepository().getBooks();

  @override
  Widget build(BuildContext context){
    return Scaffold(
      appBar: AppBar(
        title: Text('도서 목록 앱'),
      ),
      body: ListView.builder(
        itemCount: books.length,
        itemBuilder: (context,index){
          return BookTile(book:books[index]);
        },
      ),
    );
  }
}

class BookTile extends StatelessWidget{
  final Book book;
  BookTile({ required this.book });

  @override
  Widget build(BuildContext context){
    return ListTile(
      title: Text(book.title),
      leading: Image.network(book.image),
      onTap: (){
        Navigator.of(context).push(
          MaterialPageRoute(
              builder: (context)=> DetailScreen(
              book:book,
          )),
        );
      },
    );
  }
}

Main

import 'package:flutter/material.dart';
import 'package:untitled2/screens/detail_screen.dart';
import 'package:untitled2/screens/list_screen.dart';

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

class MyApp extends StatelessWidget {

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Book List APP',
      home: ListScreen(),
    );
  }
}

MediaQuery

화면의 정보(너비나 높이, 방향 등)를 알려주는 객체. 이를 활용해 화면에 비례한 위젯 크기를 설정할 수 있다.

width: MediaQuery.of(context).size.width*0.15

전체 화면 사이즈가 1이기 때문에 총합이 1이 넘지 않도록 설정해야 한다.

Model

데이터들을 객체로 만들어서 관리하기 쉽고 코드의 가독성도 높임.

Repository

서버로부터 데이터를 가져오고, 가져온 데이터를 앱에 전달하는 역할을 수행하는 코드.

0개의 댓글