23/03/27(flutter)

조영문·2023년 3월 27일
0

flutter

목록 보기
6/9

ListView

리스트뷰 -높이가 무조건 부모의 높이
컬럼 - 높이가 안정해져있음

List 메소드 3대장

foreach

요소를 뿌리는 역할

map

요소를 변경하는 역할

/flutter_basic_1/first_page.dart

//first_page.dart

import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    // 통신을 받는다.
    // 통신 데이터는 -> Json String
    // 통신에서 받아온 데이터를 파싱했다고 가정
    List<String> strList = ["첫번째", "두번째"];

    // 해당 데이터를 위젯으로 바꿔서 Children에 넣고 싶다.
    // list메소드 map은 리스트의 요소를 다른 타입으로 변경할 수 있다.

    // 요소의 타입을 String에서 Widget으로 바꾸는 함수
    final change = (String str){
      return Text(str);
    };

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


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

filter(where)

요소를 걸러내는 역할



gorouter

flutter_gorouter_v1

첫번째 상세화면(extra)

2번째 화면(extra)

3번째 화면(params)

4번째 화면(queryParams)

main.dart

import 'package:flutter/material.dart';
import 'package:flutter_gorouter_v1/routes.dart';
void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: Routes.goRouter,
    );
  }
}


routes.dart

// 라우팅을 하드코딩이 아니라 상수로 관리하면
// 나중에 라우팅을 변경할 때 편리하다.

import 'package:flutter/material.dart';
import 'package:flutter_gorouter_v1/view/first_detail_page.dart';
import 'package:flutter_gorouter_v1/view/first_page.dart';
import 'package:flutter_gorouter_v1/view/fourth_page.dart';
import 'package:flutter_gorouter_v1/view/second_page.dart';
import 'package:flutter_gorouter_v1/view/third_page.dart';
import 'package:go_router/go_router.dart';

class Routes {
  static const String first = 'first';
  static const String firstDetail = 'firstDetail';
  static const String second = 'second';
  static const String third = 'third';
  static const String fourth = 'fourth';

  static final GoRouter goRouter = GoRouter(
    navigatorKey: GlobalKey<NavigatorState>(),
    initialLocation: "/first",
    routes: [
      GoRoute(
          name: Routes.first,
          path: "/first",
          builder: (context, state) => const FirstPage(),
          routes: [
            GoRoute(
              name: Routes.firstDetail,
              path: "detail",
              builder: (context, state) => const FirstDetailPage(),
            ),
          ]
      ),
      GoRoute(
        name: Routes.second,
        path: "/second",
        builder: (context, state) => SecondPage(
          message: state.extra as String?,
        ),
      ),
      GoRoute(
        name: Routes.third,
        path: "/third",
        builder: (context, state) => ThirdPage(
          message: state.queryParams['message'],
        ),
      ),
      GoRoute(
        name: Routes.fourth,
        path: "/fourth/:message",
        builder: (context, state) => FourthPage(
          message: state.params['message'],
        ),
      ),
    ],
    errorBuilder: (context, state) => Scaffold(
      body: Center(
        child: Text('Error: ${state.error}'),
      ),
    ),
  );
}

view/first_detail_page.dart

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

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

  @override
  Widget build(BuildContext context) {

    return WillPopScope(
      onWillPop: () {
        // Navigator.pop(context, "전 페이지로 보낼 데이터");
        context.pop("전 페이지로 보낼 데이터");
        return Future.value(true);
      },
      child: Scaffold(
        appBar: AppBar(
          title: const Text('First Detail Page'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text('first detail page'),
            ],
          ),
        ),
      ),
    );
  }
}

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

view/first_page.dart

import 'package:flutter/material.dart';
import 'package:flutter_gorouter_v1/routes.dart';
import 'package:go_router/go_router.dart';

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

  @override
  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('첫번째 상세 화면 열기\n(extra)'),
              onPressed: () {
                context
                    .pushNamed(Routes.firstDetail);
              },
            ),
            const SizedBox(
              height: 20,
            ),
            ElevatedButton(
              child: const Text('두번째 화면 열기\n(extra)'),
              onPressed: () {
                context
                    // .pushNamed(Routes.second, extra: 'hello')
                    .goNamed(Routes.second, extra: 'hello');
                    // .then((value) => print(value));
              },
            ),
            const SizedBox(
              height: 20,
            ),
            ElevatedButton(
              child: const Text('세번째 화면 열기\n(params)'),
              onPressed: () {
                context.pushNamed(Routes.third, queryParams: {
                  'message': 'hello'
                }).then((value) => print(value));
              },
            ),
            const SizedBox(
              height: 20,
            ),
            ElevatedButton(
              child: const Text('네번째 화면 열기\n(queryParams)'),
              onPressed: () {
                context.pushNamed(Routes.fourth,
                    params: {'message': 'hello'}).then((value) => print(value));
              },
            ),
          ],
        ),
      ),
    );
  }
}

view/second_page.dart

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

// 이 페이지를 바로 열 경우 arguments가 null이 됨
class SecondPage extends StatelessWidget {
  final String? message;
  const SecondPage({super.key, required this.message});

  @override
  Widget build(BuildContext context) {

    return WillPopScope(
      onWillPop: () {
        // Navigator.pop(context, "전 페이지로 보낼 데이터");
        context.pop("전 페이지로 보낼 데이터");
        return Future.value(true);
      },
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Second Page'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(message ?? '잘못된 요청입니다.'),
            ],
          ),
        ),
      ),
    );
  }
}

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

view/third_page.dart

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

// 이 페이지를 바로 열 경우 arguments가 null이 됨
class ThirdPage extends StatelessWidget {
  final String? message;
  const ThirdPage({super.key, required this.message});

  @override
  Widget build(BuildContext context) {

    return WillPopScope(
      onWillPop: () {
        // Navigator.pop(context, "전 페이지로 보낼 데이터");
        context.pop("전 페이지로 보낼 데이터");
        return Future.value(true);
      },
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Third Page'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(message ?? '잘못된 요청입니다.'),
            ],
          ),
        ),
      ),
    );
  }
}

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

view/fourth_page.dart

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

// 이 페이지를 바로 열 경우 arguments가 null이 됨
class FourthPage extends StatelessWidget {
  final String? message;
  const FourthPage({super.key, required this.message});

  @override
  Widget build(BuildContext context) {

    return WillPopScope(
      onWillPop: () {
        // Navigator.pop(context, "전 페이지로 보낼 데이터");
        context.pop("전 페이지로 보낼 데이터");
        return Future.value(true);
      },
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Fourth Page'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(message ?? '잘못된 요청입니다.'),
            ],
          ),
        ),
      ),
    );
  }
}

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

통신 http

flutter_http_2

main.dart

import 'package:flutter/material.dart';
import 'package:flutter_http_2/user_page.dart';

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

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

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

post_dto.dart



class PostDTOTable{
  int id;
  String name;
  String email;

  PostDTOTable({required this.id, required this.name, required this.email});
}

user_page.dart

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

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

  @override
  Widget build(BuildContext context) {
    final listState = useState<List<PostDTOTable>?>(null);

    useEffect(() {
      String url = "https://jsonplaceholder.typicode.com/users";
      http.get(Uri.parse(url)).then((response) {
        if (response.statusCode == 200) {
          dynamic decodedBody = jsonDecode(response.body);
          List jsonList = decodedBody as List;
          listState.value = jsonList.map((data) {
            return PostDTOTable(
                id: data["id"], name: data["name"], email: data["email"]);
          }).toList();
        }
      });
    }, []);

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

class UserItem extends StatelessWidget {
  PostDTOTable postDTOTable;

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

  @override
  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.id}"),
          Divider(),
          Text("이름 : ${postDTOTable.name}"),
          Divider(),
          Text("이메일 : ${postDTOTable.email}"),
        ],
      ),
    );
  }
}

Git

위치 : flutter_example/dart_flutter_example/
https://github.com/youngmoon97/flutter_example

0개의 댓글