강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

dhgpfla0613님의 프로필 이미지
dhgpfla0613

작성한 질문수

플러터 프로그래밍 _openConnection 오류

해결된 질문

작성

·

132

0

오류한줄이 해결이 안되서 문의드립니다. 코드팩토리의 플러터프로그래밍 2판 18장입니다.

database폴더안의 drift_database.dart에서 _openConnection()부분이 오류로 뜹니다.

해당 내용은 The instance member '_openConnection' can't be accessed in an initializer. 입니다

main.dart

import 'package:calendar_scheduler2/screen/home_screen.dart';
import 'package:flutter/material.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:calendar_scheduler2/database/drift_database.dart';
import 'package:get_it/get_it.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await initializeDateFormatting();

  final database = LocalDatabase();

  GetIt.I.registerSingleton<LocalDatabase>(database);

  runApp(
    MaterialApp(
      home: HomeScreen(),
    ),
  );
}

schedule_bottom_sheet.dart

import 'package:calendar_scheduler2/component/custom_text_field.dart';
import 'package:calendar_scheduler2/const/colors.dart';
import 'package:flutter/material.dart';
import 'package:drift/drift.dart' hide Column;
import 'package:get_it/get_it.dart';
import 'package:calendar_scheduler2/database/drift_database.dart';

class ScheduleBottomSheet extends StatefulWidget {
  final DateTime selectedDate;

  const ScheduleBottomSheet({
    required this.selectedDate,Key? key}) : super(key: key);

  @override
  State<ScheduleBottomSheet> createState() => _ScheduleBottomSheetState();
}

class _ScheduleBottomSheetState extends State<ScheduleBottomSheet> {
  final GlobalKey<FormState> formKey = GlobalKey();

  int? startTime;
  int? endTime;
  String? content;

  @override
  Widget build(BuildContext context) {
    final bottomInset = MediaQuery.of(context).viewInsets.bottom;

    return Form(
      key: formKey,
      child: SafeArea(
        child: Container(
          height: MediaQuery.of(context).size.height / 2 + bottomInset,
          color: Colors.white,
          child: Padding(
            padding: EdgeInsets.only(
                left: 8, right: 8, top: 8, bottom: bottomInset),
            child: Column(
              children: [
                Row(
                  children: [
                    Expanded(
                      child: CustomTextField(
                        label: '시작 시간',
                        isTime: true,
                        onSaved: (String? val) {
                          startTime = int.parse(val!);
                        },
                        validator: timeValidator,
                      ),
                    ),
                    const SizedBox(width: 16.0),
                    Expanded(
                      child: CustomTextField(
                        label: '종료 시간',
                        isTime: true,
                        onSaved: (String? val) {
                          endTime = int.parse(val!);
                        },
                        validator: timeValidator,
                      ),
                    ),
                  ],
                ),
                SizedBox(height: 8.0),
                Expanded(
                  child: CustomTextField(
                    label: '내용',
                    isTime: false,
                    onSaved: (String? val) {
                      content = val;
                    },
                    validator: contentValidator,
                  ),
                ),
                SizedBox(
                  width: double.infinity,
                  child: ElevatedButton(
                    onPressed: onSavePressed,
                    style: ElevatedButton.styleFrom(
                      backgroundColor: PRIMARY_COLOR,
                    ),
                    child: Text('저장'),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }


  void onSavePressed() async {
    if (formKey.currentState!.validate()){
      formKey.currentState!.save();

      await GetIt.I<LocalDatabase>().createSchedule(
        SchedulesCompanion(
          startTime: Value(startTime!),
          endTime: Value(endTime!),
          content: Value(content!),
          date: Value(widget.selectedDate),
        ),
      );

      Navigator.of(context).pop();
    }
  }

  String? timeValidator(String? val) {
    if (val == null) {
      return '값을 입력해주세요';
    }

    int? number;

    try {
      number = int.parse(val);
    } catch (e) {
      return '숫자를 입력해주세요';
    }

    if (number < 0 || number > 24) {
      return '0시부터 24시 사이를 입력해주세요';
    }

    return null;
  }

  String? contentValidator(String? val) {
    if (val == null || val.length == 0) {
      return '값을 입력해주세요';
    }

    return null;
  }
}

drift_database.dart

import 'package:calendar_scheduler2/model/schedule.dart';
import 'package:drift/drift.dart';

import 'package:drift/native.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as p;
import 'dart:io';

part 'drift_database.g.dart';

@DriftDatabase(
  tables: [
    Schedules,
  ],
)
class LocalDatabase extends _$LocalDatabase {
  LocalDatabase() : super(_openConnection());

  Stream<List<Schedule>> watchSchedules(DateTime date) =>
      (select(schedules)
        ..where((tbl) => tbl.date.equals(date))).watch();


  LazyDatabase _openConnection() {
    return LazyDatabase(() async {
      final dbFolder = await getApplicationDocumentsDirectory();
      final file = File(p.join(dbFolder.path, 'db.sqlite'));
      return NativeDatabase(file);
    });
  }

  Future<int> createSchedule(SchedulesCompanion data) =>
      into(schedules).insert(data);

  Future<int> removeSchedule(int id) =>
      (delete(schedules)
        ..where((tbl) => tbl.id.equals(id))).go();

  @override
  int get schemaVersion => 1;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

답변 1

0

안녕하세요, 인프런 AI 인턴입니다.

dhgpfla0613님의 질문에 대한 답변입니다. Flutter에서 제시한 오류 메시지 “The instance member ‘_openConnection’ can’t be accessed in an initializer”는 인스턴스 멤버 ‘_openConnection’이 초기화자에서 접근될 수 없다는 것을 의미합니다. 이 문제는 LocalDatabase 클래스의 생성자에서 _openConnection 메서드를 직접 호출하여 발생합니다. Dart에서는 생성자에서 다른 인스턴스 메서드를 직접 호출할 수 없습니다. 대신 이 문제를 해결할 수 있는 한 가지 방법은 _openConnection 메서드를 static으로 만드는 것입니다.

수정된 drift_database.dart 파일의 LocalDatabase 클래스 부분:

class LocalDatabase extends _$LocalDatabase {
  LocalDatabase() : super(_openConnection());

  static LazyDatabase _openConnection() {
    return LazyDatabase(() async {
      final dbFolder = await getApplicationDocumentsDirectory();
      final file = File(p.join(dbFolder.path, 'db.sqlite'));
      return NativeDatabase(file);
    });
  }

  // 기존 코드를 여기에 포함합니다.
}

위와 같이 _openConnection 메서드를 static으로 변경함으로써 클래스 생성자에서 이 메서드를 직접 호출할 수 있게 됩니다. 이 방법은 _openConnection 메서드가 외부 인스턴스 변수나 메서드에 의존하지 않을 때 유효합니다. 게시한 코드에 따르면 _openConnection 메서드는 외부 상태에 의존하지 않으므로 이 변경이 가능하고 문제를 해결해야 합니다.

dhgpfla0613님의 프로필 이미지
dhgpfla0613

작성한 질문수

질문하기