<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>dev_seonhan.log</title>
        <link>https://velog.io/</link>
        <description>어플 개발에 관심있습니다람쥐썬더!</description>
        <lastBuildDate>Mon, 03 Jul 2023 05:26:05 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>dev_seonhan.log</title>
            <url>https://velog.velcdn.com/images/dev_seonhan/profile/162b03d5-4748-4069-a1eb-0d853eadd420/image.webp</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. dev_seonhan.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/dev_seonhan" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Flutter : Provider]]></title>
            <link>https://velog.io/@dev_seonhan/Flutter-Provider</link>
            <guid>https://velog.io/@dev_seonhan/Flutter-Provider</guid>
            <pubDate>Mon, 03 Jul 2023 05:26:05 GMT</pubDate>
            <description><![CDATA[<h3 id="provider">Provider</h3>
<blockquote>
<p><a href="https://pub.dev/packages/provider">https://pub.dev/packages/provider</a>
flutter pub add provider</p>
</blockquote>
<p>프로바이더는 위젯 트리와 상관없이 상태를 저장할 수 있게 해주는 상태 관리 라이브러리이다.
상태를 공유하는 공통 부모 위젯에 Provider를 제공하고, 상태를 사용하는 위젯에서는 Provider의 데이터를 읽어서 사용한다.
불필요한 위젯들이 rebuild 됨을 방지할 수 있다. </p>
<h4 id="watch-read-select">watch, read, select</h4>
<p>watch : 해당 위젯이 상태값의 변경을 감지한다.
read : 상태값을 읽으나 변경을 감시하지 않는다.
select : 특정 상태값만을 감시한다.</p>
<p>일반적으로 프로바이더의 값을 변경하기 위한 함수는 read를 통해 접근하고, 상태값을 사용할 때는 watch를 사용한다.</p>
<h4 id="예제">예제</h4>
<p>프로바이더를 사용하려면 ChangeNotifier를 사용해 클래스를 생성해야 한다.</p>
<p>counts_provider.dart</p>
<pre><code>class Counts with ChangeNotifier {
  int _count = 0; // 전역 변수
  int get count =&gt; _count; // 외부에서 접근할 수 있도록 getter 생성

  void add() {
    _count++;
    notifyListeners(); // 데이터가 갱신되었음을 알려줌
  }

  void remove() {
    _count--;
    notifyListeners();
  }
}
</code></pre><p>main.dart</p>
<pre><code>void main() {
  runApp(
    MaterialApp(
        home: ChangeNotifierProvider( // 최상단에 Provider 제공
      create: (_) =&gt; Counts(),
      child: const MyApp(),
    )),
  );
}

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

  @override
  State&lt;MyApp&gt; createState() =&gt; _MyAppState();
}

class _MyAppState extends State&lt;MyApp&gt; {
    @override
    Widget build(BuildContext context) {
        return Scaffold(
            body: Column(
                children: [
                    TextButton(
                        onPressed: () {
                            context.read&lt;Counts&gt;().add();
                        },
                        child: Text(&quot;add count&quot;)
                    ),
                    Text(context.watch&lt;Counts&gt;().count.toString())
                ]
            )
        )
    }
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[debug.keystore 생성 (맥북)]]></title>
            <link>https://velog.io/@dev_seonhan/sha-1-key-%EC%83%9D%EC%84%B1-%EB%A7%A5%EB%B6%81</link>
            <guid>https://velog.io/@dev_seonhan/sha-1-key-%EC%83%9D%EC%84%B1-%EB%A7%A5%EB%B6%81</guid>
            <pubDate>Sat, 01 Jul 2023 15:57:52 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>firebase google login 기능을 사용할 때 debug.keystore 파일 및 sha-1 key를 매우 힘들게 찾았던 기억이 있어, 아예 key 생성하는 방법을 기록해두려고 한다.</p>
</blockquote>
<p>1) 터미널을 실행하고 .android 파일로 이동한다.</p>
<pre><code>cd Users
cd {user name}
cd .android</code></pre><p>2) ls 명령어를 입력하여 debug.keystore 파일이 존재하는지 확인한다.</p>
<p>3-1) debug.keystore 파일이 존재할 경우, 다음의 명령어를 입력한다.</p>
<pre><code>keytool -v -list -alias androiddebugkey -keystore debug.keystore -storepass android -keypass android</code></pre><p>3-2) 존재하지 않을 경우, 다음의 명령어를 입력해 파일을 생성한다.</p>
<pre><code>keytool -genkey -v -keystore debug.keystore -storepass android -alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000

// 파일 생성 후 key를 확인하기 위해 다음 명령어를 입력한다.
keytool -v -list -alias androiddebugkey -keystore debug.keystore -storepass android -keypass android</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Flutter : ModalBottomSheet 높이 조절]]></title>
            <link>https://velog.io/@dev_seonhan/Flutter-ModalBottomSheet-%EB%86%92%EC%9D%B4-%EC%A1%B0%EC%A0%88</link>
            <guid>https://velog.io/@dev_seonhan/Flutter-ModalBottomSheet-%EB%86%92%EC%9D%B4-%EC%A1%B0%EC%A0%88</guid>
            <pubDate>Sat, 01 Jul 2023 15:45:37 GMT</pubDate>
            <description><![CDATA[<h3 id="modalbottomsheet">ModalBottomSheet()</h3>
<blockquote>
<p><a href="https://pub.dev/packages/modal_bottom_sheet">https://pub.dev/packages/modal_bottom_sheet</a>
flutter pub add modal_bottom_sheet</p>
</blockquote>
<p>isScrollControlled 속성의 값을 true로 설정해야 기본 높이보다 크게 설정할 수 있다.</p>
<pre><code>void showLongHeightModalBottomSheet(BuildContext context) {
  showModalBottomSheet(
    context: context,
    // isScrollControlled를 true로 설정한다.
    isScrollControlled: true,
    builder: (BuildContext context) {
      return Container(
        height: MediaQuery.of(context).size.height * 0.8,
      );
    },
  );
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Flutter : addPostFrameCallback]]></title>
            <link>https://velog.io/@dev_seonhan/Flutter-addPostFrameCallback</link>
            <guid>https://velog.io/@dev_seonhan/Flutter-addPostFrameCallback</guid>
            <pubDate>Sat, 01 Jul 2023 15:39:03 GMT</pubDate>
            <description><![CDATA[<h3 id="addpostframecallback">addPostFrameCallback()</h3>
<blockquote>
<p><a href="https://api.flutter.dev/flutter/scheduler/SchedulerBinding/addPostFrameCallback.html">https://api.flutter.dev/flutter/scheduler/SchedulerBinding/addPostFrameCallback.html</a></p>
</blockquote>
<p>위젯 트리가 빌드된 후에 실행되는 콜백 메서드이다.
build가 끝나기 전에 setState 또는 markNeedsBuild가 호출되었다는 에러가 발생하는 경우에 사용할 수 있다.</p>
<pre><code>WidgetsBinding.instance.addPostFrameCallback((_) {
  // 실행할 작업
});</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Flutter : WidgetsBindingObserver]]></title>
            <link>https://velog.io/@dev_seonhan/Flutter-WidgetsBindingObserver</link>
            <guid>https://velog.io/@dev_seonhan/Flutter-WidgetsBindingObserver</guid>
            <pubDate>Tue, 27 Jun 2023 06:35:59 GMT</pubDate>
            <description><![CDATA[<h3 id="widgetsbindingobserver">WidgetsBindingObserver()</h3>
<blockquote>
<p><a href="https://api.flutter.dev/flutter/widgets/WidgetsBindingObserver-class.html">https://api.flutter.dev/flutter/widgets/WidgetsBindingObserver-class.html</a></p>
</blockquote>
<p>앱의 라이프 사이클을 수신할 수 있는 클래스이다.</p>
<h4 id="methods">Methods</h4>
<pre><code>didChangeAccessibilityFeatures()
- 접근성 설정 변경 감지 
- 접근성 기능 활성화/비활성화 감지
- 테마 변경 감지 (다크 모드/라이트 모드)

didChangeAppLifecycleState(AppLifecycleState state)
- 앱 활성화/비활성화 감지
- 앱 종료 감지
- 앱 상태 관리

didChangeLocales(List&lt;Locale&gt;? locales)
- 언어 변경 감지
- 지역별 리소스 관리
- 다국어 지원

didChangeMetrics()
- 디바이스 방향 변경 감지
- 디바이스 해상도 변경 감지
- 화면 크기 변경 감지

didChangePlatformBrightness()
- 시스템 테마 변경 감지
- 밝기 모드 변경 감지
- 테마 및 스타일 변경 감지

didChangeTextScaleFactor()
- 텍스트 크기 변경 감지

didHaveMemoryPressure() 
- 메모리가 부족한 상태 감지

didPopRoute()
- 화면 이동 감지(이전 화면으로 돌아가는 경우)

didPushRoute(String route) 
- 화면 이동 감지

didPushRouteInformation(RouteInformation routeInformation) 
- 새로운 라우트 정보 푸시 감지

didRequestAppExit() 
- 앱 종료 감지</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Flutter : Animate]]></title>
            <link>https://velog.io/@dev_seonhan/Flutter-Animate</link>
            <guid>https://velog.io/@dev_seonhan/Flutter-Animate</guid>
            <pubDate>Sun, 25 Jun 2023 03:48:15 GMT</pubDate>
            <description><![CDATA[<h3 id="flutter-animate">Flutter Animate</h3>
<blockquote>
<p><a href="https://pub.dev/packages/flutter_animate">https://pub.dev/packages/flutter_animate</a>
flutter pub add flutter_animate</p>
</blockquote>
<p>Controller나 StatefulWidget을 사용하지 않고도 거의 모든 종류의 애니메이션 효과를 간단하게 추가할 수 있는 라이브러리이다.</p>
<p>애니메이션을 적용하기 위해서는 대상 위젯을 Animate 위젯으로 감싸거나, .animate() 와 같이 확장 메서드를 추가하여 사용하면 된다.</p>
<pre><code>// Animate()
Animate(
    effects: [FadeEffect(), ScaleEffect()],
    child: Text(&quot;Hello&quot;),
)

// .animate()
Text(&quot;Hello&quot;).animate().fade().scale()</code></pre><p>정말 다양하게 적용할 수 있기 때문에 많이 사용해보고 익혀두면 쏠쏠하게 활용할 수 있을 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Futter : HapticFeedback]]></title>
            <link>https://velog.io/@dev_seonhan/Futter-HapticFeedback</link>
            <guid>https://velog.io/@dev_seonhan/Futter-HapticFeedback</guid>
            <pubDate>Sun, 25 Jun 2023 03:32:42 GMT</pubDate>
            <description><![CDATA[<h3 id="hapticfeedback">HapticFeedback()</h3>
<blockquote>
<p><a href="https://api.flutter.dev/flutter/services/HapticFeedback-class.html">https://api.flutter.dev/flutter/services/HapticFeedback-class.html</a>
import &#39;package:flutter/services.dart&#39;;</p>
</blockquote>
<p>버튼을 클릭했을 때 진동 효과를 주기 위한 클래스이다.
플러터에서 기본으로 제공하는 services 패키지를 import해 사용할 수 있다.</p>
<h4 id="methods">Methods</h4>
<pre><code>HapticFeedback.heavyImpact(); // 강한 진동
HapticFeedback.mediumImpact(); // 중간 세기의 진동
HapticFeedback.lightImapct(); // 약한 진동
HapticFeedback.selectionClick(); // 값 변경(클릭)에 대한 피드백 제공
HapticFeedback.vibrate(); // 미세한 진동</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Flutter : DraggableBottomSheet]]></title>
            <link>https://velog.io/@dev_seonhan/Flutter-DraggableBottomSheet</link>
            <guid>https://velog.io/@dev_seonhan/Flutter-DraggableBottomSheet</guid>
            <pubDate>Sat, 24 Jun 2023 14:10:58 GMT</pubDate>
            <description><![CDATA[<h3 id="draggablescrollablesheet">DraggableScrollableSheet()</h3>
<blockquote>
<p><a href="https://pub.dev/packages/draggable_bottom_sheet">https://pub.dev/packages/draggable_bottom_sheet</a>
flutter pub add draggable_bottom_sheet</p>
</blockquote>
<p>채팅 화면에 FAQ UI 적용을 위해 사용한 라이브러리이다.
사용자가 드래그를 통해 위젯의 높이를 조작할 수 있다.
사용자가 조작하기 전의 기본 높이, 최대 높이, 최소 높이를 지정할 수 있다.</p>
<p>사실 원래 사용했던 것은 DraggableScrollableSheet() 위젯인데, pub dev를 보니 최근 업데이트가 무려 4년 전이라, 비교적 최근에 업데이트가 되었으면서 유사한 동작을 하는 라이브러리를 찾았다.</p>
<h4 id="arguments">Arguments</h4>
<pre><code>alignment : bottom sheet의 위치
backgroundWidget : bottom sheet를 배치할 배경 위젯
barrierColor : bottom sheet가 활성화 되었을 때 해당 sheet 바깥의 색상
barrierDismissible : bottom sheet 외부를 탭했을 때 sheet를 접을 것인지 여부 (디폴트 : true)
collapsed : bottom sheet의 초기 상태 (디폴트 : true, 접혀있는 상태)
curve : 확장 시 애니메이션
duration : 확장 시 지연 시간
expandedWidget : 확장 시 위젯
expansionExtent : previewWidget에서 expandedWidget으로 변경되기 위한 minExtent의 증분값
maxExtent : bottom sheet의 최대 높이
minExtent : bottom sheet의 최소 높이
onDragging : 드래그 시 실행되는 함수
previewWidget : bottom sheet가 비활성화 상태일 때 위젯
useSafeArea : 디바이스의 상태바, 노치 등의 화면 요소와 겹치게 할 것인지 여부 (디폴트 : true, 겹치지 않게 한다)</code></pre><p><img src="https://velog.velcdn.com/images/dev_seonhan/post/280159dd-9a88-46b0-bdab-ec2dfc02300e/image.png" alt=""></p>
]]></description>
        </item>
    </channel>
</rss>