본문 바로가기

Flutter

흔들기 앱 만들기 - 패키지 사용하기

적힌 사용법을 보고 사용하자

 

repository를 눌러서 깃허브를 살펴봐도 된다.

 

깃허브를 보고 코드 사용을 어떻게 했는지 판단하자

 

 

octotree.io 를 설치해서 깃허브를 자세히 봐도 된다.

쉽게 탐색 가능하다.

 

ctrl + y 로 줄을 삭제할 수 있다.

 

코드를 두개로 나누고 MyHomePage를 두번째 파일에 넣는다.

 

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

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

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: '흔들기 카운트 앱'),
    );
  }
}

 

 

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


class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  @override
  void initState(){
    ShakeDetector detector = ShakeDetector.autoStart(onPhoneShake: (){
      setState(() {  // counter가 올라가는 것을 화면에 반영하기 위해서 setState에 넣자
        _counter++;
      });
    },
    shakeThresholdGravity: 1.5); // 감도를 높여줘야 실행이 된다.
    super.initState();
  }

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              '흔들어서 카운트를 올려보세요',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.displayLarge,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

 

extended controls를 누르고 들어간다.

virtual sensors -> device pose -> move를 가서 조절을 한다.

 

 

 

여기서 드는 생각은 이 앱을 잠시 두고 메인 화면으로 나와서 흔들어도 올라갈까?

 

정답은 올라간다이다.

 

이번에는 백그라운드 앱 상태일 때 안 올라가도록 해보자     

 

 

 

   아래 코드처럼 수정하면 백그라운드인 상태에서는 카운팅이 되지 않는다.

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


class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

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

class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver{ // with로 선언해줘야됨
  int _counter = 0;
  late ShakeDetector detector;

  @override
  void initState(){
    WidgetsBinding.instance.addObserver(this);  // addObserver는 관찰할 대상이 필요하다.
    detector = ShakeDetector.autoStart(onPhoneShake: (){
      setState(() {  // counter가 올라가는 것을 화면에 반영하기 위해서 setState에 넣자
        _counter++;
      });
    },
    shakeThresholdGravity: 1.5);
    super.initState();
  }

  @override
  void dispose(){
    WidgetsBinding.instance.removeObserver(this);  //state 가 사라질 떄 lister를 제거해준다.
    super.dispose();
  }

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              '흔들어서 카운트를 올려보세요',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.displayLarge,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state){
    switch(state){

      case AppLifecycleState.detached:
        break;
      case AppLifecycleState.resumed:
        // resume 되면 다시 listening이 되도록 한다.
        detector.startListening();
        break;
      case AppLifecycleState.inactive:
        break;
      case AppLifecycleState.hidden:
        break;
      case AppLifecycleState.paused:
        // 화면 밖으로 나가서 멈춰있는 상태
        detector.stopListening();
        break;
    }
  }
}