inflearn logo
강의

講義

知識共有

[コードファクトリー] [初級] Flutter 3.0 アプリ開発 - 10個のプロジェクトで今日、初心者脱出!

카메라 위치 애니메이션으로 이동하기 수강중 질문

644

hyoon272316

投稿した質問数 10

0

스크린샷 2023-02-05 오후 1.53.27.png똑같이 따라 했는데

IconButton에서 mapController 사용 시

빨간줄이 뜹니다 ㅠㅠ

왜이런가요?

flutter 클론코딩 클론코딩 Flutter

回答 4

0

hyoon272316

죄송합니다...머리가 나빠서 도저히 못찾겠습니다 ㅠ

0

codefactory

mapController 변수는 HomeScreenState안에 정의돼있습니다. 그렇기때문에 mapController를 사용하려면 해당 변수를 접근하려는 함수들은 모두 HomeScreenState 안에 선언돼야해요. 이 힌트로 한번 더 파악해보세요

0

hyoon272316

강의 그대로 따라했는데 ㅠㅠ 혹시 뭐가 잘못 됬을까요?

0

codefactory

선언한 함수들의 스코프를 잘 관찰해보세요. 함수를 어디에 선언했냐에 따라 변수를 접근 가능 여부가 다릅니다. 이 힌트를 기반으로 한번 찾아보세요!

0

hyoon272316

import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  bool choolCheckDone = false;
  GoogleMapController? mapController;

  static final LatLng companyLatLng = LatLng(35.785756, 128.634620);

  static final CameraPosition initialPosition = CameraPosition(
    target: companyLatLng,
    zoom: 15,
  );

  static final double okDistance = 100;

  static final Circle withinDistanceCircle = Circle(
    circleId: CircleId('withinDistanceCircle'),
    center: companyLatLng,
    fillColor: Colors.blue.withOpacity(0.5),
    radius: okDistance,
    strokeColor: Colors.blue,
    strokeWidth: 1,
  );
  static final Circle notWithinDistanceCircle = Circle(
    circleId: CircleId('notWithinDistanceCircle'),
    center: companyLatLng,
    fillColor: Colors.red.withOpacity(0.5),
    radius: okDistance,
    strokeColor: Colors.red,
    strokeWidth: 1,
  );
  static final Circle checkDoneCircle = Circle(
    circleId: CircleId('checkDoneCircle'),
    center: companyLatLng,
    fillColor: Colors.green.withOpacity(0.5),
    radius: okDistance,
    strokeColor: Colors.green,
    strokeWidth: 1,
  );

  static final Marker marker = Marker(
    markerId: MarkerId('marker'),
    position: companyLatLng,
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: renderAppBar(),
      body: FutureBuilder(
        future: checkPermission(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Center(
              child: CircularProgressIndicator(),
            );
          }

          if (snapshot.data == '위치 권한이 허가되었습니다.') {
            return StreamBuilder<Position>(
                stream: Geolocator.getPositionStream(),
                builder: (context, snapshot) {
                  bool isWithinRange = false;

                  print(snapshot.hasData);

                  if (snapshot.hasData) {
                    final start = snapshot.data!;
                    final end = companyLatLng;

                    final distance = Geolocator.distanceBetween(
                      start.latitude,
                      start.longitude,
                      end.latitude,
                      end.longitude,
                    );

                    if (distance < okDistance) {
                      isWithinRange = true;
                    }
                  }

                  return Column(
                    children: [
                      _CustomGoogleMap(
                        initialPosition: initialPosition,
                        circle: choolCheckDone
                            ? checkDoneCircle
                            : isWithinRange
                                ? withinDistanceCircle
                                : notWithinDistanceCircle,
                        marker: marker,
                        onMapCreated: onMapCreated,
                      ),
                      _CheckButton(
                        isWithinRange: isWithinRange,
                        choolCheckDone: choolCheckDone,
                        onPressed: onCheckPressed,
                      ),
                    ],
                  );
                });
          }

          return Center(
            child: Text(snapshot.data),
          );
        },
      ),
    );
  }

  onMapCreated(GoogleMapController controller) {
    mapController = controller;
  }

  onCheckPressed() async {
    final result = await showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('출근하기'),
          content: Text('출근을 하시겠습니까?'),
          actions: [
            TextButton(
              onPressed: () {
                Navigator.of(context).pop(false);
              },
              child: Text('취소'),
            ),
            TextButton(
              onPressed: () {
                Navigator.of(context).pop(true);
              },
              child: Text('출근하기'),
            ),
          ],
        );
      },
    );

    if (result) {
      setState(() {
        choolCheckDone = true;
      });
    }
  }
}

Future<String> checkPermission() async {
  final isLocationEnabled = await Geolocator.isLocationServiceEnabled();

  if (!isLocationEnabled) {
    return '위치 서비스를 활성화 해주세요.';
  }

  LocationPermission checkedPermission = await Geolocator.checkPermission();

  if (checkedPermission == LocationPermission.denied) {
    checkedPermission = await Geolocator.requestPermission();

    if (checkedPermission == LocationPermission.denied) {
      return '위치 권한을 허가해주세요.';
    }
  }

  if (checkedPermission == LocationPermission.deniedForever) {
    return '앱의 위치 권한을 세팅에서 허가해주세요.';
  }

  return '위치 권한이 허가되었습니다.';
}

AppBar renderAppBar() {
  return AppBar(
    centerTitle: true,
    title: Text(
      '성 주 참 외',
      style: TextStyle(
        color: Colors.grey[800],
        fontWeight: FontWeight.w700,
      ),
    ),
    backgroundColor: Colors.white,
  );
}

class _CustomGoogleMap extends StatelessWidget {
  final CameraPosition initialPosition;
  final Circle circle;
  final Marker marker;
  final MapCreatedCallback onMapCreated;

  const _CustomGoogleMap({
    required this.initialPosition,
    required this.circle,
    required this.marker,
    required this.onMapCreated,
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return Expanded(
      flex: 3,
      child: GoogleMap(
        initialCameraPosition: initialPosition,
        mapType: MapType.normal,
        myLocationEnabled: true,
        myLocationButtonEnabled: true,
        circles: Set.from([circle]),
        markers: Set.from([marker]),
        onMapCreated: onMapCreated,
      ),
    );
  }
}

class _CheckButton extends StatelessWidget {
  final bool isWithinRange;
  final VoidCallback onPressed;
  final bool choolCheckDone;

  const _CheckButton(
      {required this.isWithinRange,
      required this.onPressed,
      required this.choolCheckDone,
      super.key});

  @override
  Widget build(BuildContext context) {
    return Expanded(
      flex: 1,
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Icon(
              Icons.timelapse_outlined,
              size: 50.0,
              color: choolCheckDone
                  ? Colors.green
                  : isWithinRange
                      ? Colors.blue
                      : Colors.red,
            ),
            SizedBox(
              height: 20,
            ),
            if (!choolCheckDone && isWithinRange)
              TextButton(
                onPressed: onPressed,
                child: Text(
                  '출근하기',
                  style: TextStyle(
                    color: Colors.grey[800],
                  ),
                ),
              ),
          ],
        ),
      ),
    );
  }
}

0

codefactory

안녕하세요!

질문을 하실때는 정확한 에러 메세지를 알려주셔야 도움을 드릴 수 있습니다.

제 생각엔 mapController를 정의 안하신 것 같습니다.

감사합니다.

198강 (){onTap(e);}의 이해 돕기

0

29

1

video_call 플러그인 설치후 에러 발생

0

46

1

SDK 안드로이드 설치 질문!

0

60

1

코드팩토리 디스코드 링크 다시 부탁드려요~

0

92

1

Webview를 이용해서 URL 상의 페이지 출력 불가

0

70

1

홈스크린 함수를 함축해서 main.dart에 옮기는 문제

0

55

1

플레이스토어

0

59

1

아고라 엔진 init 함수의 반환타입이 Future<void> 이것의 의미는 무엇인가요?

0

55

1

가이드라인 질문

0

57

0

emulator 에러 환경설정 뭐가 문제 일까요??

0

77

1

emulator 실행 오류

0

93

3

Column을 가로방향 최대 사이즈를 차지하도록 하는 방법에 관련

0

71

1

pubspec.yaml에서 font를 추가하면서 weight 값을 지정하는 것이 의미가 있는 것인지 문의

0

43

1

setState()를 호출하지 않으면 build가 실행 안되는 건가요?

0

53

1

video_call 플러그인 설치시 에러문제

0

64

1

children 안의 if 문에서 { } 못쓰는 이유?

0

48

1

이렇게 오류가 떠요

0

64

1

AppBar 사용했는데

0

61

2

[문제해결] '오늘도 출첵!' 의 171번 강의에서 중요한 문제를 발견했습니다

0

56

1

StatefulWidget 실습 에러가 발생합니다.[해결완료]

0

63

1

Video Player 프로젝트에 대한 추가 질문

0

53

0

Row위젯이나 column위젯의 위치는 누가 정하나요??

0

42

1

geolocator 오류때문에 개발진행이 불가능입니다

0

63

1

API 관련 이슈

0

86

2