23.03.27(Flutter)

MH S·2023년 3월 27일

Flutter

목록 보기
9/17

Routes 예제

main.dart

import 'package:flutter/material.dart';
import 'package:routes_pratice/routes.dart';
import 'package:routes_pratice/view/first_page.dart';
import 'package:routes_pratice/view/second_page.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '페이지 이동',
      routes: {
        Routes.first: (context) => const FirstPage(),
        Routes.second: (context) => const SecondPage(),
      },
      initialRoute: Routes.first,
    );
  }
}

routes.dart

// TODO Implement this library.
class Routes {
  static const String first = '/';
  static const String second = '/second';
}

first_page.dart

import 'package:flutter/material.dart';
import 'package:routes_pratice/routes.dart';

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

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('First Page'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              child: const Text('두번째 화면 열기'),
              onPressed: () {
                Navigator.pushNamed(context, Routes.second, arguments: '안녕하세요').then((value) => print(value));
              },
            ),
            const SizedBox(
              height: 20,
            ),
          ],
        ),
      ),
    );
  }
}

second_page.dart

import 'package:flutter/material.dart';

// 이 페이지를 바로 열 경우 arguments가 null이 됨
class SecondPage extends StatelessWidget {
  const SecondPage({super.key});

  
  Widget build(BuildContext context) {

    String? args;

    try {
      args = ModalRoute.of(context)?.settings.arguments as String?;
    } catch (e) {
      print(e);
    }

    return WillPopScope(
      onWillPop: () {
        Navigator.pop(context, "돌려받았습니다.");
        return Future.value(true);
      },
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Second Page'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(args ?? '잘못된 요청입니다.'),
            ],
          ),
        ),
      ),
    );
  }
}

void showToast(BuildContext context, String message) {
  final scaffold = ScaffoldMessenger.of(context);
  scaffold.showSnackBar(
    SnackBar(
      content: Text(message),
    ),
  );
}

결과화면




flutter_basic_1 (플러터 복습)

main.dart

first_page.dart

// frist_page.dart

import 'package:flutter/material.dart';

class FirstPage extends StatelessWidget {
  const FirstPage({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    // 통신을 받습니다.
    // 통신 데이터는 -> Json String
    // 통신에서 받아온 데이터를 파싱했다고 가정
    // 파싱 -> 데이터를 다른 형식으로 변경하는 것
    List<String> strList = ["첫번째", "두번째"];

    // 해당 데이터를 위젯으로 바꿔서 칠드런에 넣고 싶다
    // 방법 1. 직접 리스트를 만든다.
    // List<Widget> widgetList = [
    //   Text("첫번째"),
    //   Text("두번째"),
    // ];

    // 요소의 타입을 String에서 Widget으로 바꿀 함수
    final change = (String str) {
      return Text(str);
    };
    // 방법 2. 함수를 각각 요소에 적용한다.
    // List<Widget> widgetList =[
    //   change("첫번째"),
    //   change("두번째"),
    // ];

    // 방법 3.
    // list메소드 map은 리스트의 요소를 다른 타입으로 변경할 수 있다
    // map이 요소 각각을 change함수를 사용해서 Widget으로 변경
    // 리스트로 다시 만들어줌
    List<Widget> widgetList = strList.map(change).toList();


    return Scaffold(
      body: SafeArea(
        child: Column(
          // children은 위젯 리스트를 받는다.
          children: widgetList,
        ),
      ),
    );
  }
}

second_page.dart

import 'package:flutter/material.dart';

// 받아온 리스트 데이터를 필터링해서 변경
// 1. 필터링(where) / 2. 변경(map)
class SecondPage extends StatelessWidget {
  const SecondPage({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    // 받아온 데이터
    List<String> strList = ["apple", "google", "naver"];

    // a라는 글자가 들어간 String 만 필터링 하고 싶음
    // Text위젯 리스트로 만들고 싶음

    // String을 받아서 a가 들어있는지 확인해서
    // 있으면 true / 없으면 false를 리턴하는 함수
    final filter = (String str){
      return str.contains("a");
    };

    // String 을 Widget으로 변경하는 함수
    // 같은 Widget를 리스트로 사용해서 출력할 경우
    // key를 녛어 줘야 한다.
    final change = (String str) {
      return Text(str, key: UniqueKey(),);
    };

    List<Widget> widgetList = strList.where(filter).map(change).toList();

    return Scaffold(
      body: SafeArea(
        child: Column(
          children: widgetList,
        ),
      ),
    );
  }
}

third_page.dart

// third_page.dart

// 객체 리스틀 받아서 화면 구성
import 'package:flutter/material.dart';

class ThirdPage extends StatelessWidget {
  const ThirdPage({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    // 파싱된 데이터
    List<Post> postList = [
      Post(userId: 0, id: 0, title: "제목1", body: "내용1"),
      Post(userId: 1, id: 1, title: "제목2", body: "내용2"),
    ];

    // map 에서 이용할 요소를 바꾸는 함수
    final change = (Post post){
      return Row(
        children: [
          Text("유저번호 : ${post.userId} | "),
          Text("글번호 : ${post.id} | "),
          Text("제목 : ${post.title} | "),
          Text("내용 : ${post.body}"),
        ],
      );
    };


    return Scaffold(
      body: SafeArea(
          child: Column(
            children: postList.map(change).toList(),
          )),
    );
  }
}

class Post {
  int userId;
  int id;
  String title;
  String body;

  Post({required this.userId, required this.id, required this.title, required this.body});
}

void main(){
  Post post1 = new Post(
      userId: 0,
      id: 0,
      title: "title",
      body: "conetent"
  );
}



통신

pubspec.yaml


추가하기

main.dart

import 'package:flutter/material.dart';
import 'package:flutter_http_1/list_page.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: ListPage(),
    );
  }
}

post_dto.dart

// 테이블 용
class PostDTOTable {
  int userId; // 유저 번호
  int id; // 글 번호
  String title;
}

// 상세 페이지 용
class PostDTODetail {
  int userId;
  int id;
  String title;
  String body;
}

위 코드에서

alt + insert ->

모두 선택후 ok 누르기

// post_dto.dart

// 테이블 용
class PostDTOTable {
  int userId; // 유저 번호
  int id; // 글 번호
  String title;
  PostDTOTable({required this.userId, required this.id, required this.title});
}

// 상세 페이지 용
class PostDTODetail {
  int userId;
  int id;
  String title;
  String body;

  PostDTODetail(
      {required this.userId,
        required this.id,
        required this.title,
        required this.body});
}

list_page.dart (json url 에 값을 받아와 출력)

// list_page.dart

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_http_1/post_dto.dart';
import 'package:http/http.dart' as http;

class ListPage extends HookWidget {
  const ListPage({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    // 더미데이터
    //PostDTOTable postDTOTable = PostDTOTable(userId: 0, id: 0, title: "테스트 제목");

    // 실제 데이터
    // 통신은 실패할 수 있다
    final listState = useState<List<PostDTOTable>?>(null);
    final jsonState = useState<String?>(null);

    // useEffect(작동함수, 관찰할 상태 리스트);
    // 빌드가 완료되면 작동한다
    // 관찰하는 상태가 변동되면 작동한다
    // 관찰하는 상태가 없으면 반드시 1번 작동한다.
    useEffect((){
      String url = "https://jsonplaceholder.typicode.com/posts";
      http.get(Uri.parse(url)).then((response) => {
        jsonState.value = response.body
      });
    },[]);


    return Scaffold(
      body: SafeArea(
          child: ListView(
            children: [
              Text(jsonState.value ?? "값이 없습니다"),
            ],
          )
      ),
    );
  }
}

class ListItem extends StatelessWidget {
  PostDTOTable postDTOTable;

  ListItem({Key? key, required this.postDTOTable}) : super(key: key);

  
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(10),
      decoration: BoxDecoration(border: Border.all(width: 2, color: Colors.black)),
      child: Column(
        children: [
          ListItem(postDTOTable: postDTOTable),
          ListItem(postDTOTable: postDTOTable),
          ListItem(postDTOTable: postDTOTable),
        ],
      ),
    );
  }
}

list_page.dart (json url 에 값을 받아와 리스트로 출력)

// list_page.dart

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:flutter_http_1/post_dto.dart';
import 'package:http/http.dart' as http;

class ListPage extends HookWidget {
  const ListPage({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    // 더미데이터
    // PostDTOTable postDTOTable = PostDTOTable(userId: 0, id: 0, title: "테스트 제목");

    // 실제 데이터
    // 통신은 실패할 수 있다 = nullable
    final listState = useState<List<PostDTOTable>?>(null);

    // final jsonState = useState<String?>(null);

    // useEffect(작동함수, 관찰할 상태 리스트);
    // 빌드가 완료되면 작동한다
    // 관찰하는 상태가 변경되면 작동한다
    // 관찰하는 상태가 없으면 빌드 시 1번 작동한다.
    useEffect(() {
      String url = "https://jsonplaceholder.typicode.com/posts";
      http.get(Uri.parse(url)).then((response) {
        // 정상적으로 받아왔는지 체크
        // 200은 정상 응답
        if (response.statusCode == 200) {
          // string을 json형식으로 파싱
          dynamic decodedBody = jsonDecode(response.body);
          // json을 Map List로 캐스팅
          List jsonList = decodedBody as List;
          // List를 map 함수로 풀어서
          // 요소를 PostDTOTable로 변경
          // state에 입력
          listState.value = jsonList.map((data) {
            return PostDTOTable(
                userId: data["userId"], id: data["id"], title: data["title"]);
          }).toList();
        }

        // jsonState.value = response.body;
      });
    }, []);

    return Scaffold(
      body: SafeArea(
        child: ListView(
          children: listState.value?.map((e) => ListItem(postDTOTable: e)).toList() ?? [],
        ),
      ),
    );
  }
}

class ListItem extends StatelessWidget {
  PostDTOTable postDTOTable;

  ListItem({Key? key, required this.postDTOTable}) : super(key: key);

  
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(10),
      decoration: BoxDecoration(
        border: Border.all(width: 2, color: Colors.black),
      ),
      child: Column(
        children: [
          Text("유저번호 : ${postDTOTable.userId}"),
          Divider(),
          Text("글 번호 : ${postDTOTable.id}"),
          Divider(),
          Text("글 제목 : ${postDTOTable.title}"),
        ],
      ),
    );
  }
}

0개의 댓글