반응형

변수의 초기화는 변수에 값을 할당하여 사용할 준비를 하는 과정입니다.

Dart에서는 변수를 선언할 때 초기화하지 않으면 기본값이 할당되지만, 명시적으로 초기화하는 것이 좋습니다.

이는 코드의 명확성을 높이고, 런타임 오류를 방지할 수 있습니다.

 

Dart에서 변수 초기화

 

1. 기본 초기화

변수를 선언할 때 초기값을 바로 할당할 수 있습니다.

void main() {
  int number = 10;       // 정수형 변수 초기화
  double decimal = 3.14; // 실수형 변수 초기화
  String text = "Hello"; // 문자열 변수 초기화
  bool isTrue = true;    // 불리언 변수 초기화

  print(number);  // 10
  print(decimal); // 3.14
  print(text);    // Hello
  print(isTrue);  // true
}

 

2. Null Safety와 late 키워드

 

Dart의 Null Safety 기능을 사용하면 변수를 선언할 때 초기화를 강제할 수 있습니다. late 키워드를 사용하면 변수를 나중에 초기화할 수 있습니다.

void main() {
  late String description;

  description = "This is a description"; // 나중에 초기화
  print(description); // This is a description
}

 

3. final과 const

 

finalconst 키워드를 사용하면 상수 값을 초기화할 수 있습니다. final은 런타임에 초기화할 수 있지만, const는 컴파일 타임에 초기화해야 합니다.

void main() {
  final int number = 42;       // 런타임 상수
  const double pi = 3.14159;   // 컴파일 타임 상수

  print(number); // 42
  print(pi);     // 3.14159
}

4. 동적 타입 변수

 

Dart에서는 var, dynamic 키워드를 사용하여 동적 타입의 변수를 선언하고 초기화할 수 있습니다.

void main() {
  var number = 10;          // Dart가 타입을 추론 (int)
  dynamic text = "Hello";   // 동적 타입, 초기값에 따라 타입이 결정됨

  print(number); // 10
  print(text);   // Hello

  text = 42;     // dynamic 타입이므로 다른 타입의 값 할당 가능
  print(text);   // 42
}

변수 초기화의 중요성

 

1. 명확성: 변수를 선언할 때 초기값을 할당하면, 코드의 의도를 명확히 할 수 있습니다.

2. 안정성: 초기화되지 않은 변수를 사용하면 예기치 않은 오류가 발생할 수 있습니다. 초기화를 통해 이러한 오류를 방지할 수 있습니다.

3. Null Safety: Dart의 Null Safety 기능을 통해 변수를 초기화하지 않으면 컴파일 타임에 오류가 발생합니다. 이를 통해 Null 참조 오류를 방지할 수 있습니다.

 

예제: 클래스와 초기화

 

클래스의 인스턴스 변수를 초기화하는 예제입니다.

class Person {
  String name;
  int age;

  // 생성자를 통해 변수 초기화
  Person(this.name, this.age);

  // 네임드 생성자를 통해 초기화
  Person.withDefaultName(this.age) : name = 'Unknown';
}

void main() {
  var person1 = Person('John', 30);
  var person2 = Person.withDefaultName(25);

  print('${person1.name}, ${person1.age}'); // John, 30
  print('${person2.name}, ${person2.age}'); // Unknown, 25
}

 

결론

 

변수 초기화는 코드의 명확성, 안정성, Null Safety를 보장하기 위해 중요합니다. Dart에서는 다양한 방법으로 변수를 초기화할 수 있으며, final, const, late 키워드를 사용하여 다양한 초기화 시나리오를 처리할 수 있습니다. 초기화를 올바르게 사용하여 안정적이고 명확한 코드를 작성하세요.

 

1. Dart Language Tour - Variables:

이 문서는 Dart에서 변수 선언과 초기화에 대한 기본적인 개념과 사용법을 설명합니다.

Dart Language Tour - Variables

2. Dart Language Tour - Null Safety:

이 문서는 Null Safety와 관련된 개념을 다루며, 변수 초기화와 관련된 사항을 자세히 설명합니다.

Dart Language Tour - Null Safety

3. Dart Language Tour - Late Variables:

이 문서는 late 키워드를 사용하여 변수를 나중에 초기화하는 방법에 대해 설명합니다.

Dart Language Tour - Late Variables

반응형
반응형

Dart 3 버전은 다양한 개선 사항과 새로운 기능을 도입하여 개발자 경험을 향상시키고 성능을 최적화합니다. 주요 변경 사항과 새로운 기능은 다음과 같습니다:

 

주요 변경 사항 및 새로운 기능

 

1. Null Safety 강화

Null Safety는 Dart 2.12에서 도입되었지만, Dart 3에서는 더 강력한 Null Safety 기능을 제공합니다. 모든 코드가 Null Safety를 적용해야 하며, 이를 통해 Null 참조 오류를 사전에 방지할 수 있습니다.

2. Records

Dart 3에서는 새로운 데이터 구조인 Records를 도입했습니다. Records는 여러 값을 간단히 묶어 표현할 수 있는 구조로, 튜플과 유사합니다. 이는 특히 함수에서 여러 값을 반환할 때 유용합니다.

 

(int, String) recordExample() {
  return (42, "Hello");
}

void main() {
  var record = recordExample();
  print(record.$1); // 42
  print(record.$2); // Hello
}

 

 

3. Pattern Matching

Dart 3에서는 Pattern Matching을 도입하여 데이터 구조의 특정 패턴을 쉽게 매칭하고 처리할 수 있습니다. 이는 코드를 더 간결하고 명확하게 작성할 수 있게 합니다.

void main() {
  var value = (42, "Hello");
  if (value case (int number, String message)) {
    print('Number: $number, Message: $message');
  }
}

4. Enhanced Enumerations

Dart 3에서는 열거형(enumerations)에 기능을 추가하여 더 강력하게 사용할 수 있습니다. 이제 열거형에 속성과 메서드를 추가할 수 있으며, 이를 통해 더 복잡한 상태를 관리할 수 있습니다.

enum Status {
  success(200),
  notFound(404),
  serverError(500);

  final int code;

  const Status(this.code);
}

void main() {
  print(Status.success.code); // 200
}

5. Faster Compilation and Improved Performance

Dart 3는 컴파일러 성능을 향상시켜 더 빠른 빌드 시간을 제공합니다. 또한, 런타임 성능도 개선되어 애플리케이션이 더 빠르게 실행됩니다.

6. Better Interoperability with JavaScript

Dart 3는 JavaScript와의 상호 운용성을 개선하여 웹 애플리케이션 개발이 더욱 원활해졌습니다. 이를 통해 Dart 코드를 JavaScript 코드와 더 쉽게 통합할 수 있습니다.

7. Enhanced Tooling and Developer Experience

Dart 3는 개선된 도구와 개발자 경험을 제공합니다. 예를 들어, Dart 분석기와 디버거가 더 많은 기능과 향상된 성능을 제공합니다.

 

Dart 3의 주요 목표

 

안정성: Null Safety와 같은 기능을 통해 코드의 안정성을 높이고, 런타임 오류를 줄입니다.

생산성: Records, Pattern Matching, Enhanced Enumerations와 같은 기능을 통해 개발자가 더 생산적으로 코드를 작성할 수 있도록 돕습니다.

성능: 더 빠른 컴파일 시간과 향상된 런타임 성능을 제공하여 개발자와 최종 사용자 모두에게 더 나은 성능을 제공합니다.

호환성: JavaScript와의 상호 운용성을 개선하여 웹 애플리케이션 개발을 더 쉽게 만듭니다.

 

결론

 

Dart 3는 다양한 새로운 기능과 개선 사항을 도입하여 개발자 경험을 향상시키고 성능을 최적화합니다. Null Safety 강화, Records, Pattern Matching, Enhanced Enumerations, 더 빠른 컴파일과 성능 개선, JavaScript와의 상호 운용성 개선 등은 Dart 3의 주요 특징입니다. 이를 통해 Dart는 더욱 강력하고 효율적인 프로그래밍 언어가 되었습니다.

반응형
반응형

Dart 란

 

Dart는 모든 플랫폼에서 사용할 수 있는 앱을 개발하기 위해 탄생한 클라이언트 최적화된 언어

구글에서 201110월에 공개했으며 멀티 플랫폼 상에서 동작되도록 하는 앱을 개발하기 위해 디자인됨

Dart의 목표는 다양한 종류의 기기에서 동작되도록 하는 것

 

특징

기본적으로 C언어의 문법과 비슷하며 Java, C#, Javascript와 같은 구조를 갖춤

DVM(Dart VM), 네이티브 컴파일링을 통해 모바일, 데스크탑, 웹 등의 환경에서 앱 실행을 지원

Flutter라는 프레임워크의 주 언어로 사용됨

 

주요 특징

 

1. 간결하고 강력한 문법: Dart는 이해하기 쉽고 생산성을 높이는 간결한 문법을 가지고 있습니다.

2. 정적 타입 언어: Dart는 정적 타입 언어로, 컴파일 타임에 타입 검사를 수행합니다. 이를 통해 코드의 안전성을 높이고 버그를 줄일 수 있습니다.

3. 클래스 기반 객체 지향: Dart는 객체 지향 언어로, 클래스와 상속을 지원합니다.

4. 동시성 지원: asyncawait 키워드를 통해 비동기 프로그래밍을 간단하게 구현할 수 있습니다.

5. 크로스 플랫폼: Dart는 모바일, 웹, 데스크탑 등 여러 플랫폼에서 실행될 수 있습니다.

6. 빠른 컴파일 속도: Dart는 JIT(Just-In-Time) 컴파일과 AOT(Ahead-Of-Time) 컴파일을 지원하여 빠른 실행 속도를 제공합니다.

 

공식지원 IDE

안드로이드 스튜디오

인텔리제이

VS Code 

변수 선언

void main() {
  int a = 10;
  double b = 3.14;
  String name = "Dart";
  bool isActive = true;

  print(a);
  print(b);
  print(name);
  print(isActive);
}

함수 정의

void main() {
  printGreeting('John');
  int result = add(2, 3);
  print('Sum: $result');
}

void printGreeting(String name) {
  print('Hello, $name');
}

int add(int a, int b) {
  return a + b;
}

조건문과 반복문

void main() {
  int number = 5;

  if (number > 0) {
    print('Positive');
  } else if (number < 0) {
    print('Negative');
  } else {
    print('Zero');
  }

  for (int i = 0; i < 5; i++) {
    print('i: $i');
  }

  int j = 0;
  while (j < 5) {
    print('j: $j');
    j++;
  }
}

 

클래스와 객체

void main() {
  var person = Person(name: 'John', age: 30);
  person.greet();
}

class Person {
  String name;
  int age;

  Person({required this.name, required this.age});

  void greet() {
    print('Hello, my name is $name and I am $age years old.');
  }
}

 

객체 지향 프로그래밍

 

Dart는 객체 지향 프로그래밍(OOP)을 지원합니다. OOP는 코드 재사용성과 확장성을 높이는 데 도움이 됩니다. Dart에서는 클래스, 상속, 다형성, 추상화 등을 통해 OOP를 구현할 수 있습니다.

void main() {
  var dog = Dog(name: 'Buddy', age: 3);
  dog.bark();
  dog.describe();
}

class Animal {
  String name;
  int age;

  Animal({required this.name, required this.age});

  void describe() {
    print('This is $name and it is $age years old.');
  }
}

class Dog extends Animal {
  Dog({required String name, required int age}) : super(name: name, age: age);

  void bark() {
    print('Woof! Woof!');
  }
}

 

비동기 프로그래밍

 

Dart는 비동기 프로그래밍을 간단하게 구현할 수 있는 키워드인 asyncawait를 제공합니다. 이를 통해 비동기 작업을 쉽게 처리할 수 있습니다.

 

void main() async {
  print('Fetching data...');
  String data = await fetchData();
  print('Data: $data');
}

Future<String> fetchData() async {
  await Future.delayed(Duration(seconds: 2));
  return 'Hello from the future!';
}

 

그 외 특징

- 모든 변수는 객체이며 모든 객체는 클래스의 인스턴스임

  - 숫자, 함수, Null도 객체로 취급

- Dart 2 버전부터 Null Safety를 소개하고 있음

- Dart는 데이터 타입을 가지고 있음

- Dart는 Generic 타입을 지원

- Dart는 main()과 같은 top-level 함수를 지원

- Dart는 public, protected, private와 같은 키워드를 지원하지 않음

  - 만약 식별자 이름 앞에 언더바(_)를 붙이면 라이브러리에서 private으로 설정할 수 있음

- Dart는 삼항 연산자를 지원

 

레퍼런스

1. Dart 공식 사이트: Dart 언어의 공식 사이트로, Dart에 대한 기본적인 소개와 문서, 튜토리얼 등을 제공합니다.

Dart 공식 사이트

2. Dart 언어 투어: Dart 언어의 문법과 기능을 체계적으로 설명하는 가이드입니다.

Dart 언어 투어

3. Dart 패키지 문서: Dart 패키지 및 라이브러리에 대한 문서입니다.

Dart 패키지 문서

4. Dart API 문서: Dart의 코어 라이브러리 및 API에 대한 상세한 문서입니다.

Dart API 문서

5. Dart Null Safety 문서: Dart의 Null Safety 기능에 대한 소개와 사용 방법을 설명하는 문서입니다.

Dart Null Safety 문서

6. Dart Code Labs: Dart와 Flutter를 배우기 위한 실습형 튜토리얼입니다.

Dart Code Labs

7. Dart GitHub 리포지토리: Dart 언어의 소스 코드와 관련 자료를 확인할 수 있는 GitHub 리포지토리입니다.

Dart GitHub 리포지토리

 

반응형
반응형

BottomNavigationBar는 Flutter에서 화면 하단에 배치하여 여러 화면으로 쉽게 전환할 수 있도록 도와주는 네비게이션 바입니다.

일반적으로 3~5개의 탭을 가지며, 각 탭을 선택하면 해당 화면으로 이동할 수 있습니다.

 

주요 속성

 

items: 네비게이션 바에 표시될 항목 목록 (BottomNavigationBarItem).

currentIndex: 현재 선택된 항목의 인덱스.

onTap: 항목이 탭될 때 호출되는 콜백 함수.

type: 네비게이션 바의 유형 (fixed 또는 shifting).

backgroundColor: 네비게이션 바의 배경색.

selectedItemColor: 선택된 항목의 색상.

unselectedItemColor: 선택되지 않은 항목의 색상.

 

기본 사용 예제

 

아래는 BottomNavigationBar를 사용하여 화면 하단에 네비게이션 바를 배치하고, setState를 사용하여 화면을 업데이트하는 예제입니다.

 

코드 예제 

import 'package:flutter/material.dart';

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
  
  late TabController _tabController;
  int _selectedIndex = 0;
  
  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 3, vsync: this);
    _tabController.addListener(
      () => setState(() => _selectedIndex = _tabController.index)
    );
  }

  // 페이지 종료 시 종료해 주는 기능
  @override
  void dispose() {
    super.dispose();

  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("test title"),
        ),
        body: _selectedIndex == 0
      ? tabContainer(context, Colors.indigo, "Friends Tab")
        : _selectedIndex == 1 ? tabContainer(context, Colors.yellow, "Chats Tab")
        : tabContainer(context, Colors.blue, "Setting Tab"),
      bottomNavigationBar: SizedBox(
        height: 90,
        child: TabBar(
          controller: _tabController,
          labelColor: Colors.black,
          tabs: [
            Tab(
             icon: Icon(
                 _selectedIndex == 0 ? Icons.person : Icons.person_2_outlined
             ),
             text: "Friends",
            ),
            Tab(
              icon: Icon(
                  _selectedIndex == 1 ? Icons.chat : Icons.chat_outlined
              ),
              text: "Chats",
            ),
            Tab(
              icon: Icon(
                  _selectedIndex == 2 ? Icons.settings : Icons.settings_outlined
              ),
              text: "Settings",
            ),
          ],
        ),
      ),
    );
  }

  Widget tabContainer(BuildContext con, Color tabColor, String tabText) {
    return Container(
      width: MediaQuery.of(con).size.width,
      height: MediaQuery.of(con).size.height,
      color: tabColor,
      child: Center(
        child: Text(
          tabText,
          style: const TextStyle(
            color: Colors.white
          ),
        ),
      ),
    );
  }

}

 

 

다른 예제 

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  int _selectedIndex = 0;

  static const List<Widget> _widgetOptions = <Widget>[
    Text(
      'Home Page',
      style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold),
    ),
    Text(
      'Search Page',
      style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold),
    ),
    Text(
      'Profile Page',
      style: TextStyle(fontSize: 35, fontWeight: FontWeight.bold),
    ),
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('BottomNavigationBar Example'),
      ),
      body: Center(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.search),
            label: 'Search',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.person),
            label: 'Profile',
          ),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Colors.amber[800],
        onTap: _onItemTapped,
      ),
    );
  }
}

 

주요 포인트

 

1. BottomNavigationBarItem: 네비게이션 바에 표시될 항목을 정의합니다. iconlabel 속성을 가집니다.

2. currentIndex: 현재 선택된 항목의 인덱스를 저장합니다.

3. onTap: 항목이 탭될 때 호출되는 콜백 함수로, 선택된 인덱스를 업데이트하고 화면을 새로 고칩니다.

4. setState: 상태 변화를 적용하여 UI를 다시 빌드합니다.

 

BottomNavigationBar와 setState 설명

 

BottomNavigationBar

 

BottomNavigationBar는 하단 네비게이션 바를 만드는 데 사용됩니다. 여러 개의 탭을 제공하여 각 탭에 다른 화면을 연결할 수 있습니다.

 

items: BottomNavigationBarItem 목록으로, 각 항목에는 iconlabel이 포함됩니다.

currentIndex: 현재 선택된 탭의 인덱스를 지정합니다.

onTap: 탭이 선택될 때 호출되는 콜백 함수로, 탭의 인덱스를 매개변수로 받습니다.

 

setState

 

setState는 상태가 변경될 때 UI를 다시 빌드하는 데 사용됩니다. 네비게이션 바의 선택된 인덱스를 업데이트할 때 호출됩니다.

 

setState(): 내부 상태를 업데이트하고 변경된 상태를 반영하기 위해 UI를 다시 빌드합니다. 상태 변경이 필요할 때마다 호출해야 합니다.

 

요약

 

BottomNavigationBar는 Flutter에서 화면 하단에 네비게이션 바를 배치하여 여러 화면으로 쉽게 전환할 수 있도록 도와줍니다.

setState는 상태 변경 시 UI를 다시 빌드하는 데 사용됩니다.

BottomNavigationBarsetState를 함께 사용하여 탭 선택 시 화면을 업데이트할 수 있습니다.

반응형
반응형

sharedPreferences는 Flutter에서 간단한 키-값 쌍을 영구적으로 저장하는 데 사용되는 패키지입니다.

이 패키지는 Android의 SharedPreferences와 iOS의 NSUserDefaults를 래핑합니다.

작은 데이터를 영구적으로 저장하고자 할 때 유용합니다.

 

주요 기능

 

데이터 저장: 문자열, 정수, 부울, 더블 등의 간단한 데이터를 저장할 수 있습니다.

데이터 읽기: 저장된 데이터를 읽어올 수 있습니다.

데이터 삭제: 특정 키에 해당하는 데이터를 삭제할 수 있습니다.

모든 데이터 삭제: 모든 데이터를 삭제할 수 있습니다.

 

1. 패키지 추가

 

pubspec.yaml 파일에 shared_preferences 패키지를 추가합니다.

dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.0.6

 

2. 패키지 가져오기

 

Dart 파일에서 shared_preferences 패키지를 가져옵니다.

import 'package:shared_preferences/shared_preferences.dart';

 

3. 데이터 저장

 

데이터를 저장하는 예제입니다.

Future<void> saveData() async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.setString('username', 'John Doe');
  await prefs.setInt('age', 30);
  await prefs.setBool('isLoggedIn', true);
  await prefs.setDouble('height', 1.75);
}

4. 데이터 읽기

 

저장된 데이터를 읽어오는 예제입니다.

Future<void> readData() async {
  final prefs = await SharedPreferences.getInstance();
  String? username = prefs.getString('username');
  int? age = prefs.getInt('age');
  bool? isLoggedIn = prefs.getBool('isLoggedIn');
  double? height = prefs.getDouble('height');

  print('Username: $username');
  print('Age: $age');
  print('Is Logged In: $isLoggedIn');
  print('Height: $height');
}

 

5. 데이터 삭제

 

특정 키에 해당하는 데이터를 삭제하는 예제입니다.

Future<void> removeData() async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.remove('username');
}

6. 모든 데이터 삭제

 

모든 데이터를 삭제하는 예제입니다.

Future<void> clearData() async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.clear();
}



예시 

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  late SharedPreferences _prefs;
  String _username = "";
  final TextEditingController _userController = TextEditingController();

  @override
  void initState() {
    super.initState();
    _getUsername();
  }

  _saveUsername() {
    setState(() {
      _username = _userController.text;
      _prefs.setString("currentUsername", _username);
    });
  }

  _getUsername() async {
    _prefs = await SharedPreferences.getInstance();
    setState(() {
      _username = _prefs.getString("currentUsername") ?? "";
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("test title"),
        ),
        body: Container(
          child: Column(
            children: [
              Text("현재 사용자 이름 : $_username" ),
              Container(
                child: TextField(
                  controller: _userController,
                  textAlign: TextAlign.left,
                  decoration: const InputDecoration(
                    border: InputBorder.none,
                    hintText: 'Input your username'
                  ),
                ),
              ),
              TextButton(
                  onPressed: () => _saveUsername()
                  , child: Text('저장')
              )
            ],
          ),
        )

    );
  }
}



다른 예제 앱

 

간단한 예제 앱을 만들어 보겠습니다.

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

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  late SharedPreferences prefs;
  String username = '';
  int age = 0;
  bool isLoggedIn = false;
  double height = 0.0;

  @override
  void initState() {
    super.initState();
    _loadData();
  }

  Future<void> _loadData() async {
    prefs = await SharedPreferences.getInstance();
    setState(() {
      username = prefs.getString('username') ?? '';
      age = prefs.getInt('age') ?? 0;
      isLoggedIn = prefs.getBool('isLoggedIn') ?? false;
      height = prefs.getDouble('height') ?? 0.0;
    });
  }

  Future<void> _saveData() async {
    await prefs.setString('username', 'John Doe');
    await prefs.setInt('age', 30);
    await prefs.setBool('isLoggedIn', true);
    await prefs.setDouble('height', 1.75);
    _loadData();
  }

  Future<void> _removeData() async {
    await prefs.remove('username');
    _loadData();
  }

  Future<void> _clearData() async {
    await prefs.clear();
    _loadData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('SharedPreferences Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text('Username: $username'),
            Text('Age: $age'),
            Text('Is Logged In: $isLoggedIn'),
            Text('Height: $height'),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _saveData,
              child: Text('Save Data'),
            ),
            ElevatedButton(
              onPressed: _removeData,
              child: Text('Remove Username'),
            ),
            ElevatedButton(
              onPressed: _clearData,
              child: Text('Clear All Data'),
            ),
          ],
        ),
      ),
    );
  }
}

 

주요 포인트

 

SharedPreferences: 간단한 키-값 쌍을 영구적으로 저장하는 데 사용됩니다.

getInstance(): SharedPreferences의 인스턴스를 얻기 위해 사용됩니다.

setString, setInt, setBool, setDouble: 데이터를 저장하는 메서드입니다.

getString, getInt, getBool, getDouble: 데이터를 읽어오는 메서드입니다.

remove: 특정 키에 해당하는 데이터를 삭제하는 메서드입니다.

clear: 모든 데이터를 삭제하는 메서드입니다.

 

SharedPreferences 문서

 

SharedPreferences 패키지 문서

 

 

반응형
반응형

 

1. JSON 파일 추가 및 등록: JSON 파일을 assets 폴더에 추가하고 pubspec.yaml 파일에 등록합니다.

 

{
  "users": [
    {
      "id": 1,
      "username": "Anna",
      "email": "anna@gmail.com"
    },
    {
      "id": 2,
      "username": "David",
      "email": "david@gmail.com"
    },
    {
      "id": 3,
      "username": "brian",
      "email": "brian@gmail.com"
    },
    {
      "id": 4,
      "username": "roky",
      "email": "roky@gmail.com"
    },
    {
      "id": 5,
      "username": "sam",
      "email": "sam@gmail.com"
    },
    {
      "id": 6,
      "username": "dead",
      "email": "dead@gmail.com"
    }
  ]
}

 

2. JSON 파일 읽기 및 파싱

 

dart:convertflutter/services.dart 패키지를 사용하여 JSON 파일을 읽고 파싱합니다.

 

static Future loadJson() async {
    final String response = await rootBundle.loadString("lib/users.json");
    final data = await json.decode(response);
    return data['users'];
  }

  Future userList = loadJson();

 

3. 위젯에 데이터 노출하기

Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("test title"),
        ),
        body: Container(
          child: FutureBuilder(
            future: userList,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return ListView.builder(
                  itemCount: snapshot.data.length,
                    itemBuilder: (context, index) {
                      return Container(
                        padding: const EdgeInsets.all(10),
                        child: Text(
                            "${snapshot.data[index]["id"]}: ${snapshot.data[index]["username"]}"
                        ),
                      );
                    }
                );
              } else if (snapshot.hasError) {
                return const Center(
                  child: Text("Error"),
                );
              } else {
                return const Center(
                    child: CircularProgressIndicator(
                        strokeWidth: 2,
                    )
                );
              }
            },
          ),
        )
    )

결과물

 

반응형
반응형

 

Flutter 앱에서 YouTube 동영상을 가져와 표시하기 위해 youtube_player_flutter 패키지를 사용할 수 있습니다. 이 패키지는 YouTube 동영상을 임베드할 수 있는 위젯을 제공합니다. 아래는 Flutter 프로젝트에서 YouTube 동영상을 가져와 표시하는 방법을 단계별로 설명합니다.

단계별 가이드

 

1. 패키지 설치

 

pubspec.yaml 파일에 youtube_player_flutter 패키지를 추가합니다.

dependencies:
  flutter:
    sdk: flutter
  youtube_player_flutter: ^8.0.0

 

2. 패키지 가져오기

 

Dart 파일에서 youtube_player_flutter 패키지를 가져옵니다.

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

 

3. YouTube Player Controller 설정

 

YouTube 동영상을 제어할 수 있는 컨트롤러를 설정합니다. 컨트롤러를 사용하여 동영상을 로드하고 재생합니다.

유튜브 삽입 코드

static String youtubeId = 't5Vj0jeYeEE';

final YoutubePlayerController _con = YoutubePlayerController(
  initialVideoId: youtubeId,
  flags: const YoutubePlayerFlags(
      autoPlay: false
  )
);

@override
Widget build(BuildContext context) {
  return Scaffold(
      appBar: AppBar(
        title: const Text("test title"),
      ),
      body: Center(
        child: YoutubePlayer(
          controller: _con,
          showVideoProgressIndicator: true,
          onReady: () {
            print('Player is ready.');
          },
        ),
      )
  );
}

 

반응형
반응형

Navigator 위젯은 Flutter에서 화면 간의 네비게이션을 관리하는 데 사용됩니다.

Flutter 앱은 일반적으로 여러 화면(Screen)으로 구성되며, 사용자가 다양한 화면 간을 이동할 수 있도록 Navigator를 사용합니다. Navigator는 스택(Stack) 자료구조를 사용하여 화면을 관리합니다.

새로운 화면을 푸시(Push)하고 이전 화면을 팝(Pop)하는 방식으로 작동합니다.

 

주요 메서드

 

1. push: 새로운 화면을 스택에 추가합니다.

2. pop: 현재 화면을 스택에서 제거합니다.

3. pushReplacement: 현재 화면을 새 화면으로 교체합니다.

4. pushAndRemoveUntil: 특정 조건에 따라 스택의 모든 화면을 제거하고 새로운 화면을 추가합니다.

5. popUntil: 특정 조건에 따라 스택의 화면을 제거합니다.

 

 

현재 페이지에서 새로만든 SecondView 라는 페이지로 이동을 원할 경우

body: Center(
  child: GestureDetector(
    onTap: () => Navigator.push(context, MaterialPageRoute(
        builder: (_) => SecondView())
    ),
    child: Container(
      padding: EdgeInsets.all(15),
      color: Colors.blue,
      child: Text("Get Started"),
    ),
  ),
)

이동하는 페이지에서는 다음과 같이 구현할 수 있습니다. 

뒤로가기 아이콘의 onPressed 에 pop() 이라는 메소드로 현재 위로 올라온 페이지를 제거하여 뒤로 가는 방법입니다. 

import 'package:flutter/material.dart';

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

  @override
  State<SecondView> createState() => _SecondViewState();
}

class _SecondViewState extends State<SecondView> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          leading: IconButton(
            icon: Icon(Icons.arrow_back),
            onPressed: () => Navigator.of(context).pop(),
          ),
          title: const Text("test title"),
        ),
        body: Center(
          child: Container(
            padding: EdgeInsets.all(15),
            color: Colors.blue,
            child: Text("This is the second view"),
          ),
        )
    );
  }
}

 

 

 

다른 예시

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: FirstPage(),
    );
  }
}

class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Page'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pushReplacement(
              context,
              MaterialPageRoute(builder: (context) => SecondPage()),
            );
          },
          child: Text('Go to Second Page'),
        ),
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Page'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pushReplacement(
              context,
              MaterialPageRoute(builder: (context) => FirstPage()),
            );
          },
          child: Text('Go Back to First Page'),
        ),
      ),
    );
  }
}

 

3. pushAndRemoveUntil

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: FirstPage(),
    );
  }
}

class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Page'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => SecondPage()),
            );
          },
          child: Text('Go to Second Page'),
        ),
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Page'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pushAndRemoveUntil(
              context,
              MaterialPageRoute(builder: (context) => ThirdPage()),
              (Route<dynamic> route) => false,
            );
          },
          child: Text('Go to Third Page and remove all previous pages'),
        ),
      ),
    );
  }
}

class ThirdPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Third Page'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('Go Back'),
        ),
      ),
    );
  }
}

 

 

 

주요 포인트

 

push: 새로운 화면을 스택에 추가합니다.

pop: 현재 화면을 스택에서 제거합니다.

pushReplacement: 현재 화면을 새 화면으로 교체하고, 이전 화면을 스택에서 제거합니다.

pushAndRemoveUntil: 특정 조건에 따라 스택의 모든 화면을 제거하고 새로운 화면을 추가합니다.

popUntil: 특정 조건에 따라 스택의 화면을 제거합니다.

 

추가 메서드

 

canPop: 현재 화면이 스택에서 팝될 수 있는지 확인합니다.

maybePop: 팝될 수 있는 경우 화면을 팝합니다.

popAndPushNamed: 현재 화면을 팝하고 새로운 화면을 이름으로 푸시합니다.

pushNamed: 이름으로 새로운 화면을 푸시합니다.

 

Navigator 문서

 

Navigator 클래스 문서

MaterialPageRoute 클래스 문서

반응형

+ Recent posts