<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>혀가 길지 않은 개발자</title>
    <link>https://jwsoft91.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Fri, 3 Jul 2026 22:44:17 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>혀가 길지 않은 개발자</managingEditor>
    <image>
      <title>혀가 길지 않은 개발자</title>
      <url>https://tistory1.daumcdn.net/tistory/3696967/attach/e8a7367fa5434935ac8f88abee229e1f</url>
      <link>https://jwsoft91.tistory.com</link>
    </image>
    <item>
      <title>[Android] 에뮬레이터 추가</title>
      <link>https://jwsoft91.tistory.com/281</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;안드로이드 스튜디오에 원하는 기기 에뮬레이터 추가&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.samsung.com/galaxy-emulator-skin/guide.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.samsung.com/galaxy-emulator-skin/guide.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android</category>
      <category>Android</category>
      <category>안드로이드</category>
      <author>혀가 길지 않은 개발자</author>
      <guid isPermaLink="true">https://jwsoft91.tistory.com/281</guid>
      <comments>https://jwsoft91.tistory.com/281#entry281comment</comments>
      <pubDate>Sun, 12 Dec 2021 13:48:21 +0900</pubDate>
    </item>
    <item>
      <title>[Kotlin] &amp;nbsp;암호화와 복호화</title>
      <link>https://jwsoft91.tistory.com/280</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;암호화 (AES256, BLOWFISH)&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;복호화&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Hash 함수를 통과 하기전의 원본 데이터를 메시지(message)라고 부르고, 통과된 이후의 데이터를 다이제스트(digest)라고 부른다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. AES/ECB/PKCS5PADDING 방식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;plaintext&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cipher&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ciphertext&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. AES/CBC/PKCS5PADDING 방식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iv&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;plaintext&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cipher&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ciphertext&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. key값의 길이에 따라 AES128, AES192, AES256 으로 구분됨&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; AES128 : 키값 16bytes&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; AES192 : 키값 24bytes&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; AES256 : 키값 32bytes&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MainActivity.kt&lt;/p&gt;
&lt;pre id=&quot;code_1623061185813&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.example.encryptionexample

import android.os.Bundle
import android.util.Base64
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec

class MainActivity : AppCompatActivity() {

    companion object {
        const val SECRET_KEY = &quot;ABCDEFGH12345678&quot;
        const val SECRET_IV = &quot;1234567812345678&quot;
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val encrypted = &quot;안녕하세요!!!&quot;.encryptECB()
        val decrypted = encrypted.decryptECB()

        Log.e(&quot;&quot;, encrypted)
        Log.e(&quot;&quot;, decrypted)

        val encryptedCBC = &quot;Hello~!!!&quot;.encryptCBC()
        val decryptedCBC = encryptedCBC.decryptCBC()

        Log.e(&quot;&quot;, encryptedCBC)
        Log.e(&quot;&quot;, decryptedCBC)
    }

    /**
     * ECB 암호화
     */
    private fun String.encryptECB(): String{
        val keySpec = SecretKeySpec(SECRET_KEY.toByteArray(), &quot;AES&quot;)    /// 키
        val cipher = Cipher.getInstance(&quot;AES/ECB/PKCS5PADDING&quot;)     //싸이퍼
        cipher.init(Cipher.ENCRYPT_MODE, keySpec)       // 암호화/복호화 모드
        val ciphertext = cipher.doFinal(this.toByteArray())
        val encodedByte = Base64.encode(ciphertext, Base64.DEFAULT)
        return String(encodedByte)
    }

    /**
     * ECB 복호화
     */
    private fun String.decryptECB(): String {
        val keySpec = SecretKeySpec(SECRET_KEY.toByteArray(), &quot;AES&quot;)
        var decodedByte: ByteArray = Base64.decode(this, Base64.DEFAULT)
        val cipher = Cipher.getInstance(&quot;AES/ECB/PKCS5PADDING&quot;)
        cipher.init(Cipher.DECRYPT_MODE, keySpec)
        val output = cipher.doFinal(decodedByte)

        return String(output)
    }

    /**
     * CBC 암호화
     */
    private fun String.encryptCBC(): String{
        val iv = IvParameterSpec(SECRET_IV.toByteArray())
        val keySpec = SecretKeySpec(SECRET_KEY.toByteArray(), &quot;AES&quot;)    /// 키
        val cipher = Cipher.getInstance(&quot;AES/CBC/PKCS5PADDING&quot;)     //싸이퍼
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv)       // 암호화/복호화 모드
        val crypted = cipher.doFinal(this.toByteArray())
        val encodedByte = Base64.encode(crypted, Base64.DEFAULT)

        return String(encodedByte)
    }

    /**
     * CBC 복호화
     */
    private fun String.decryptCBC(): String {
        var decodedByte: ByteArray = Base64.decode(this, Base64.DEFAULT)
        val iv = IvParameterSpec(SECRET_IV.toByteArray())
        val keySpec = SecretKeySpec(SECRET_KEY.toByteArray(), &quot;AES&quot;)
        val cipher = Cipher.getInstance(&quot;AES/CBC/PKCS5PADDING&quot;)
        cipher.init(Cipher.DECRYPT_MODE, keySpec, iv)
        val output = cipher.doFinal(decodedByte)

        return String(output)
    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1762&quot; data-origin-height=&quot;174&quot; data-filename=&quot;스크린샷 2021-06-07 오후 7.20.38.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBwPVW/btq6DSJRvf2/giQ0kKgrjF9Ba103OKX7ok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBwPVW/btq6DSJRvf2/giQ0kKgrjF9Ba103OKX7ok/img.png&quot; data-alt=&quot;실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBwPVW/btq6DSJRvf2/giQ0kKgrjF9Ba103OKX7ok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBwPVW%2Fbtq6DSJRvf2%2FgiQ0kKgrjF9Ba103OKX7ok%2Fimg.png&quot; data-origin-width=&quot;1762&quot; data-origin-height=&quot;174&quot; data-filename=&quot;스크린샷 2021-06-07 오후 7.20.38.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.android.com/guide/topics/security/cryptography?hl=ko&quot;&gt;https://developer.android.com/guide/topics/security/cryptography?hl=ko&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1622968873894&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;암호화 &amp;nbsp;|&amp;nbsp; Android 개발자 &amp;nbsp;|&amp;nbsp; Android Developers&quot; data-og-description=&quot;Android의 암호화 기능을 알아보세요.&quot; data-og-host=&quot;developer.android.com&quot; data-og-source-url=&quot;https://developer.android.com/guide/topics/security/cryptography?hl=ko&quot; data-og-url=&quot;https://developer.android.com/guide/topics/security/cryptography?hl=ko&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bigLnA/hyKuxxrZKR/pSXGD2bN1xfJcRulVGUXN0/img.png?width=1201&amp;amp;height=676&amp;amp;face=0_0_1201_676&quot;&gt;&lt;a href=&quot;https://developer.android.com/guide/topics/security/cryptography?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.android.com/guide/topics/security/cryptography?hl=ko&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bigLnA/hyKuxxrZKR/pSXGD2bN1xfJcRulVGUXN0/img.png?width=1201&amp;amp;height=676&amp;amp;face=0_0_1201_676');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;암호화 &amp;nbsp;|&amp;nbsp; Android 개발자 &amp;nbsp;|&amp;nbsp; Android Developers&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Android의 암호화 기능을 알아보세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.android.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Encoding ? Enctyption ?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/4657416/difference-between-encoding-and-encryption&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://stackoverflow.com/questions/4657416/difference-between-encoding-and-encryption&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1622971098644&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Difference between encoding and encryption&quot; data-og-description=&quot;What is the difference between encoding and encryption?&quot; data-og-host=&quot;stackoverflow.com&quot; data-og-source-url=&quot;https://stackoverflow.com/questions/4657416/difference-between-encoding-and-encryption&quot; data-og-url=&quot;https://stackoverflow.com/questions/4657416/difference-between-encoding-and-encryption&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bz3uN4/hyKuv0JghR/51CkLbtzLvkqWcjjpdEcf0/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/4657416/difference-between-encoding-and-encryption&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://stackoverflow.com/questions/4657416/difference-between-encoding-and-encryption&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bz3uN4/hyKuv0JghR/51CkLbtzLvkqWcjjpdEcf0/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Difference between encoding and encryption&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;What is the difference between encoding and encryption?&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;stackoverflow.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CBC? ECB?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;amp;blogId=jsky10503&amp;amp;logNo=221258926405&quot;&gt;https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;amp;blogId=jsky10503&amp;amp;logNo=221258926405&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1622980372884&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;블록암호와 운용방식(ECB, CBC, CTR)&quot; data-og-description=&quot;블록암호(block cipher)란 기밀성있는 정보를 고정된 크기의 블록단위로 구성하여 암호화 작업을 하는 대칭...&quot; data-og-host=&quot;blog.naver.com&quot; data-og-source-url=&quot;https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;amp;blogId=jsky10503&amp;amp;logNo=221258926405&quot; data-og-url=&quot;https://blog.naver.com/jsky10503/221258926405&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bBSGM7/hyKurD68jA/gYLq0M52KC0aPakqqsbUjk/img.png?width=743&amp;amp;height=545&amp;amp;face=0_0_743_545,https://scrap.kakaocdn.net/dn/kKPNh/hyKtchvLnH/mYl4mECkVzCVLJgBZdQtdK/img.png?width=80&amp;amp;height=58&amp;amp;face=0_0_80_58,https://scrap.kakaocdn.net/dn/cyhasr/hyKuBzXR8N/ZKsUo13b2vHknL3Wq0EMJ1/img.png?width=80&amp;amp;height=59&amp;amp;face=0_0_80_59&quot;&gt;&lt;a href=&quot;https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;amp;blogId=jsky10503&amp;amp;logNo=221258926405&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&amp;amp;blogId=jsky10503&amp;amp;logNo=221258926405&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bBSGM7/hyKurD68jA/gYLq0M52KC0aPakqqsbUjk/img.png?width=743&amp;amp;height=545&amp;amp;face=0_0_743_545,https://scrap.kakaocdn.net/dn/kKPNh/hyKtchvLnH/mYl4mECkVzCVLJgBZdQtdK/img.png?width=80&amp;amp;height=58&amp;amp;face=0_0_80_58,https://scrap.kakaocdn.net/dn/cyhasr/hyKuBzXR8N/ZKsUo13b2vHknL3Wq0EMJ1/img.png?width=80&amp;amp;height=59&amp;amp;face=0_0_80_59');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;블록암호와 운용방식(ECB, CBC, CTR)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;블록암호(block cipher)란 기밀성있는 정보를 고정된 크기의 블록단위로 구성하여 암호화 작업을 하는 대칭...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://happinessoncode.com/2019/04/06/java-cipher-algorithm-mode-padding/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://happinessoncode.com/2019/04/06/java-cipher-algorithm-mode-padding/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1622980843936&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Java Cipher - 알고리즘, 운용 모드, 패딩의 이해&quot; data-og-description=&quot;자바에서는 대칭키 알고리즘을 사용하여 데이터를 암호화/복호화할 때 javax.crypto.Cipher 클래스를 사용한다. 이 클래스의 인스턴스는 정적 메서드인 Cipher.getInstance()를 호출하여 가져올 수 있는데,&quot; data-og-host=&quot;happinessoncode.com&quot; data-og-source-url=&quot;http://happinessoncode.com/2019/04/06/java-cipher-algorithm-mode-padding/&quot; data-og-url=&quot;http://happinessoncode.com/2019/04/06/java-cipher-algorithm-mode-padding/index.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/VM8yJ/hyKtel6sFZ/6YAJMdI7t8xUc7fCrnEIkK/img.png?width=712&amp;amp;height=912&amp;amp;face=0_0_712_912,https://scrap.kakaocdn.net/dn/dp26pa/hyKs5WZWiw/1k8XdK5l847tNNz2WQk5sK/img.png?width=1202&amp;amp;height=484&amp;amp;face=0_0_1202_484,https://scrap.kakaocdn.net/dn/buyVT6/hyKtdOgOfC/Px0kb7G5gDG4CPnJGnCbB1/img.jpg?width=196&amp;amp;height=216&amp;amp;face=0_0_196_216,https://scrap.kakaocdn.net/dn/csrxmR/hyKuut5sNG/cE4qtsb2LSsbQpESPxK0Ik/img.png?width=712&amp;amp;height=912&amp;amp;face=0_0_712_912&quot;&gt;&lt;a href=&quot;http://happinessoncode.com/2019/04/06/java-cipher-algorithm-mode-padding/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://happinessoncode.com/2019/04/06/java-cipher-algorithm-mode-padding/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/VM8yJ/hyKtel6sFZ/6YAJMdI7t8xUc7fCrnEIkK/img.png?width=712&amp;amp;height=912&amp;amp;face=0_0_712_912,https://scrap.kakaocdn.net/dn/dp26pa/hyKs5WZWiw/1k8XdK5l847tNNz2WQk5sK/img.png?width=1202&amp;amp;height=484&amp;amp;face=0_0_1202_484,https://scrap.kakaocdn.net/dn/buyVT6/hyKtdOgOfC/Px0kb7G5gDG4CPnJGnCbB1/img.jpg?width=196&amp;amp;height=216&amp;amp;face=0_0_196_216,https://scrap.kakaocdn.net/dn/csrxmR/hyKuut5sNG/cE4qtsb2LSsbQpESPxK0Ik/img.png?width=712&amp;amp;height=912&amp;amp;face=0_0_712_912');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Java Cipher - 알고리즘, 운용 모드, 패딩의 이해&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;자바에서는 대칭키 알고리즘을 사용하여 데이터를 암호화/복호화할 때 javax.crypto.Cipher 클래스를 사용한다. 이 클래스의 인스턴스는 정적 메서드인 Cipher.getInstance()를 호출하여 가져올 수 있는데,&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;happinessoncode.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android/Kotlin</category>
      <category>Android</category>
      <category>Kotlin</category>
      <category>복호화</category>
      <category>안드로이드</category>
      <category>암호화</category>
      <category>코틀린</category>
      <author>혀가 길지 않은 개발자</author>
      <guid isPermaLink="true">https://jwsoft91.tistory.com/280</guid>
      <comments>https://jwsoft91.tistory.com/280#entry280comment</comments>
      <pubDate>Sun, 6 Jun 2021 17:48:39 +0900</pubDate>
    </item>
    <item>
      <title>[Kotlin] &amp;nbsp;Lifecycle, LifecycleOwner, LifecycleObserver</title>
      <link>https://jwsoft91.tistory.com/279</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Lifecycle&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LifecycleOwner&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LifecycleObserver&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MainActivity.kt&lt;/p&gt;
&lt;pre id=&quot;code_1622959535079&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.example.lifecycleexample

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Button
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver

class MainActivity : AppCompatActivity() {

    private val btShow: Button by lazy {
        findViewById(R.id.bt_show)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val bottomLifecycleObserver = LifecycleEventObserver { source, event -&amp;gt;
            when (source.lifecycle.currentState) {
                Lifecycle.State.CREATED -&amp;gt; Log.e(&quot;&quot;, &quot;MainActivity :: Lifecycle.State.CREATED&quot;)
                Lifecycle.State.STARTED -&amp;gt; Log.e(&quot;&quot;, &quot;MainActivity :: Lifecycle.State.STARTED&quot;)
                Lifecycle.State.DESTROYED -&amp;gt; Log.e(&quot;&quot;, &quot;MainActivity :: Lifecycle.State.DESTROYED&quot;)
            }

            when (event) {
                Lifecycle.Event.ON_CREATE -&amp;gt; Log.e(&quot;&quot;, &quot;MainActivity :: Lifecycle.Event.ON_CREATE&quot;)
                Lifecycle.Event.ON_START -&amp;gt; Log.e(&quot;&quot;, &quot;MainActivity :: Lifecycle.Event.ON_START&quot;)
                Lifecycle.Event.ON_RESUME -&amp;gt; Log.e(&quot;&quot;, &quot;MainActivity :: Lifecycle.Event.ON_RESUME&quot;)
                Lifecycle.Event.ON_PAUSE -&amp;gt; Log.e(&quot;&quot;, &quot;MainActivity :: Lifecycle.Event.ON_PAUSE&quot;)
                Lifecycle.Event.ON_STOP -&amp;gt; Log.e(&quot;&quot;, &quot;MainActivity :: Lifecycle.Event.ON_STOP&quot;)
                Lifecycle.Event.ON_DESTROY -&amp;gt; Log.e(&quot;&quot;, &quot;MainActivity :: Lifecycle.Event.ON_DESTROY&quot;)
            }
        }

        btShow.setOnClickListener {
            TestDialog().apply {
                lifecycleObserver = bottomLifecycleObserver
            }.show(supportFragmentManager, &quot;TestDialog&quot;)

        }
    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다이얼로그의 생명주기에 반응하여 로그를 출력. (LifecycleObserver)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TestDialog.kt&lt;/p&gt;
&lt;pre id=&quot;code_1622959619984&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.example.lifecycleexample

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.LifecycleObserver
import com.google.android.material.bottomsheet.BottomSheetDialogFragment

class TestDialog : BottomSheetDialogFragment() {

    lateinit var lifecycleObserver: LifecycleObserver

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        Log.e(&quot;&quot;, &quot;TestDialog :: onCreate()&quot;)
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        viewLifecycleOwner.lifecycle.addObserver(lifecycleObserver)
        Log.e(&quot;&quot;, &quot;TestDialog :: onCreateView()&quot;)
        return inflater.inflate(R.layout.dialog_test, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        Log.e(&quot;&quot;, &quot;TestDialog :: onViewCreated()&quot;)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        Log.e(&quot;&quot;, &quot;TestDialog :: onActivityCreated()&quot;)
    }

    override fun onStart() {
        super.onStart()
        Log.e(&quot;&quot;, &quot;TestDialog :: onStart()&quot;)
    }

    override fun onResume() {
        super.onResume()
        Log.e(&quot;&quot;, &quot;TestDialog :: onResume()&quot;)
    }

    override fun onPause() {
        super.onPause()
        Log.e(&quot;&quot;, &quot;TestDialog :: onPause()&quot;)
    }

    override fun onStop() {
        super.onStop()
        Log.e(&quot;&quot;, &quot;TestDialog :: onStop()&quot;)
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.e(&quot;&quot;, &quot;TestDialog :: onDestroy()&quot;)
    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MainActivity 에서 생선한 lifecycleObserver 를 다이얼로그의 생명주기에 추가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;viewLifecycleOwner.lifecycle.addObserver(lifecycleObserver)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;552&quot; data-origin-height=&quot;1200&quot; data-filename=&quot;2021-06-06 15.11.06.gif&quot; width=&quot;256&quot; height=&quot;557&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdG2XN/btq6DCsgjUb/kF4PraRtmHLZu2swSJAJZk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdG2XN/btq6DCsgjUb/kF4PraRtmHLZu2swSJAJZk/img.gif&quot; data-alt=&quot;실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdG2XN/btq6DCsgjUb/kF4PraRtmHLZu2swSJAJZk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bdG2XN/btq6DCsgjUb/kF4PraRtmHLZu2swSJAJZk/img.gif&quot; data-origin-width=&quot;552&quot; data-origin-height=&quot;1200&quot; data-filename=&quot;2021-06-06 15.11.06.gif&quot; width=&quot;256&quot; height=&quot;557&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;492&quot; data-filename=&quot;스크린샷 2021-06-06 오후 3.12.27.png&quot; width=&quot;402&quot; height=&quot;254&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vtIRb/btq6BaJPXkw/NRW3pm8oXvf82UlktIBy1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vtIRb/btq6BaJPXkw/NRW3pm8oXvf82UlktIBy1k/img.png&quot; data-alt=&quot;다이얼로그 띄웠을 때&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vtIRb/btq6BaJPXkw/NRW3pm8oXvf82UlktIBy1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvtIRb%2Fbtq6BaJPXkw%2FNRW3pm8oXvf82UlktIBy1k%2Fimg.png&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;492&quot; data-filename=&quot;스크린샷 2021-06-06 오후 3.12.27.png&quot; width=&quot;402&quot; height=&quot;254&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;다이얼로그 띄웠을 때&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;396&quot; data-filename=&quot;스크린샷 2021-06-06 오후 3.13.01.png&quot; width=&quot;403&quot; height=&quot;208&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kX0NJ/btq6EWjIZpu/pafOLixMQ8ZQa183UZlQz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kX0NJ/btq6EWjIZpu/pafOLixMQ8ZQa183UZlQz1/img.png&quot; data-alt=&quot;다이얼로그 없어졌을 때&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kX0NJ/btq6EWjIZpu/pafOLixMQ8ZQa183UZlQz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkX0NJ%2Fbtq6EWjIZpu%2FpafOLixMQ8ZQa183UZlQz1%2Fimg.png&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;396&quot; data-filename=&quot;스크린샷 2021-06-06 오후 3.13.01.png&quot; width=&quot;403&quot; height=&quot;208&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;다이얼로그 없어졌을 때&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android/Kotlin</category>
      <category>Android</category>
      <category>Kotlin</category>
      <category>LifeCycle</category>
      <category>LifecycleObserver</category>
      <category>LifecycleOwner</category>
      <category>안드로이드</category>
      <category>코틀린</category>
      <author>혀가 길지 않은 개발자</author>
      <guid isPermaLink="true">https://jwsoft91.tistory.com/279</guid>
      <comments>https://jwsoft91.tistory.com/279#entry279comment</comments>
      <pubDate>Sat, 5 Jun 2021 21:37:33 +0900</pubDate>
    </item>
    <item>
      <title>[Kotlin]&amp;nbsp; registerForActivityResult</title>
      <link>https://jwsoft91.tistory.com/278</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;startActivityForResult()&lt;/s&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;onActivityResult()&lt;/s&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;registerForResultActivity&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ActivityResultLauncher&amp;lt;Intent&amp;gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;registerForActivityResult&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ActivityResultContracts.StartActivityForResult()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ActivityResultLauncher.launch(intent)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;activity_main.xml&lt;/p&gt;
&lt;pre id=&quot;code_1622147701593&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    tools:context=&quot;.MainActivity&quot;&amp;gt;

    &amp;lt;TextView
        android:id=&quot;@+id/tv_main&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:textSize=&quot;30dp&quot;
        tools:text=&quot;Main&quot;
        app:layout_constraintVertical_chainStyle=&quot;packed&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot;
        app:layout_constraintBottom_toTopOf=&quot;@+id/bt_main&quot; /&amp;gt;

    &amp;lt;androidx.appcompat.widget.AppCompatButton
        android:id=&quot;@+id/bt_main&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:text=&quot;move to SubActivity&quot;
        android:textAllCaps=&quot;false&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintLeft_toLeftOf=&quot;parent&quot;
        app:layout_constraintRight_toRightOf=&quot;parent&quot;
        app:layout_constraintTop_toBottomOf=&quot;@+id/tv_main&quot; /&amp;gt;

&amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1648&quot; data-origin-height=&quot;1384&quot; data-filename=&quot;스크린샷 2021-05-28 오전 5.43.47.png&quot; width=&quot;428&quot; height=&quot;359&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dht0gF/btq5R0B74Hv/tDOLE0VTIzE3hh2AQiim4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dht0gF/btq5R0B74Hv/tDOLE0VTIzE3hh2AQiim4K/img.png&quot; data-alt=&quot;activity_main.xml&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dht0gF/btq5R0B74Hv/tDOLE0VTIzE3hh2AQiim4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdht0gF%2Fbtq5R0B74Hv%2FtDOLE0VTIzE3hh2AQiim4K%2Fimg.png&quot; data-origin-width=&quot;1648&quot; data-origin-height=&quot;1384&quot; data-filename=&quot;스크린샷 2021-05-28 오전 5.43.47.png&quot; width=&quot;428&quot; height=&quot;359&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;activity_main.xml&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Activity_sub.xml&lt;/p&gt;
&lt;pre id=&quot;code_1622147770032&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;&amp;gt;

    &amp;lt;androidx.appcompat.widget.AppCompatButton
        android:id=&quot;@+id/bt_sub&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:text=&quot;back&quot;
        android:textAllCaps=&quot;false&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintLeft_toLeftOf=&quot;parent&quot;
        app:layout_constraintRight_toRightOf=&quot;parent&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot; /&amp;gt;

&amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1510&quot; data-origin-height=&quot;1272&quot; data-filename=&quot;스크린샷 2021-05-28 오전 5.36.19.png&quot; width=&quot;453&quot; height=&quot;382&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dC87Ou/btq5XG298c2/zZMaWRi4LsgrWBHJlDV0BK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dC87Ou/btq5XG298c2/zZMaWRi4LsgrWBHJlDV0BK/img.png&quot; data-alt=&quot;activity_sub.xml&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dC87Ou/btq5XG298c2/zZMaWRi4LsgrWBHJlDV0BK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdC87Ou%2Fbtq5XG298c2%2FzZMaWRi4LsgrWBHJlDV0BK%2Fimg.png&quot; data-origin-width=&quot;1510&quot; data-origin-height=&quot;1272&quot; data-filename=&quot;스크린샷 2021-05-28 오전 5.36.19.png&quot; width=&quot;453&quot; height=&quot;382&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;activity_sub.xml&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SubActivity.kt&lt;/p&gt;
&lt;pre id=&quot;code_1622147841414&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.example.registerforresultactivityexample

import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatButton

class SubActivity : AppCompatActivity() {

    private val btSub: AppCompatButton by lazy { findViewById(R.id.bt_sub) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sub)

        btSub.setOnClickListener {
            val intent = Intent(this, MainActivity::class.java).apply {
                putExtra(&quot;address&quot;, &quot;Seoul&quot;)
            }
            setResult(RESULT_OK, intent)
            if (!isFinishing) finish()
        }
    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MainActivity.kt&lt;/p&gt;
&lt;pre id=&quot;code_1622256255997&quot; class=&quot;kotlin&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 20px; color: #383a42; background: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; cursor: default; z-index: 1;&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.example.registerforresultactivityexample

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.widget.AppCompatButton

class MainActivity : AppCompatActivity() {

    private val btMain: AppCompatButton by lazy { findViewById(R.id.bt_main) }
    private val tvMain: TextView by lazy { findViewById(R.id.tv_main) }

    lateinit var activityResultLauncher: ActivityResultLauncher&amp;lt;Intent&amp;gt;

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        btMain.setOnClickListener {
            activityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
                if (it.resultCode == RESULT_OK) {
                    val address = it.data?.getStringExtra(&quot;address&quot;) ?: &quot;&quot;
                    tvMain.text = address
                }
            }

            val intent = Intent(this, SubActivity::class.java)
            activityResultLauncher.launch(intent)
        }
    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;1076&quot; data-filename=&quot;2021-05-29 11.45.44.gif&quot; width=&quot;263&quot; height=&quot;555&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DXkyM/btq51710vSc/bipIB3JN74xEzZAWVmKWvK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DXkyM/btq51710vSc/bipIB3JN74xEzZAWVmKWvK/img.gif&quot; data-alt=&quot;실행 결과 에러 발생&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DXkyM/btq51710vSc/bipIB3JN74xEzZAWVmKWvK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/DXkyM/btq51710vSc/bipIB3JN74xEzZAWVmKWvK/img.gif&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;1076&quot; data-filename=&quot;2021-05-29 11.45.44.gif&quot; width=&quot;263&quot; height=&quot;555&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실행 결과 에러 발생&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;????????&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;3186&quot; data-origin-height=&quot;534&quot; data-filename=&quot;스크린샷 2021-05-29 오전 11.47.01.png&quot; width=&quot;956&quot; height=&quot;160&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bB8q42/btq53QxZiPi/GzUruntWNKFwuD6uikIt70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bB8q42/btq53QxZiPi/GzUruntWNKFwuD6uikIt70/img.png&quot; data-alt=&quot;에러 발생&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bB8q42/btq53QxZiPi/GzUruntWNKFwuD6uikIt70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbB8q42%2Fbtq53QxZiPi%2FGzUruntWNKFwuD6uikIt70%2Fimg.png&quot; data-origin-width=&quot;3186&quot; data-origin-height=&quot;534&quot; data-filename=&quot;스크린샷 2021-05-29 오전 11.47.01.png&quot; width=&quot;956&quot; height=&quot;160&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;에러 발생&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;onResume() 에서 registerForActivityResult() 호출하면 에러가 발생함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;onCreate() 아니면 onStart() 에서 사용해야 함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MainActivity.kt&lt;/p&gt;
&lt;pre id=&quot;code_1622256586912&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.example.registerforresultactivityexample

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.widget.AppCompatButton

class MainActivity : AppCompatActivity() {

    private val btMain: AppCompatButton by lazy { findViewById(R.id.bt_main) }
    private val tvMain: TextView by lazy { findViewById(R.id.tv_main) }

    lateinit var activityResultLauncher: ActivityResultLauncher&amp;lt;Intent&amp;gt;

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        activityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
            if (it.resultCode == RESULT_OK) {
                val address = it.data?.getStringExtra(&quot;address&quot;) ?: &quot;&quot;
                tvMain.text = address
            }
        }

        btMain.setOnClickListener {
            val intent = Intent(this, SubActivity::class.java)
            activityResultLauncher.launch(intent)
        }
    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;1080&quot; data-filename=&quot;2021-05-29 10.54.31.gif&quot; width=&quot;274&quot; height=&quot;578&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Dvy9b/btq50ZpzC3f/yZzakjNRrnepb7OU1Oh2lK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Dvy9b/btq50ZpzC3f/yZzakjNRrnepb7OU1Oh2lK/img.gif&quot; data-alt=&quot;실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Dvy9b/btq50ZpzC3f/yZzakjNRrnepb7OU1Oh2lK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/Dvy9b/btq50ZpzC3f/yZzakjNRrnepb7OU1Oh2lK/img.gif&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;1080&quot; data-filename=&quot;2021-05-29 10.54.31.gif&quot; width=&quot;274&quot; height=&quot;578&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러 발생 시 참고.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/65121235/fatal-error-lifecycleowners-must-call-register-before-they-are-started-on-regist&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://stackoverflow.com/questions/65121235/fatal-error-lifecycleowners-must-call-register-before-they-are-started-on-regist&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1622256618327&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Fatal error LifecycleOwners must call register before they are STARTED on registerForActivityResult&quot; data-og-description=&quot;I have a simple empty activity that checks if permissions need to be requested. When registerForActivityResult is called, it crashes with the error java.lang.IllegalStateException: LifecycleOwner com.&quot; data-og-host=&quot;stackoverflow.com&quot; data-og-source-url=&quot;https://stackoverflow.com/questions/65121235/fatal-error-lifecycleowners-must-call-register-before-they-are-started-on-regist&quot; data-og-url=&quot;https://stackoverflow.com/questions/65121235/fatal-error-lifecycleowners-must-call-register-before-they-are-started-on-regist&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/J6WVl/hyKnqljy96/DGVIBjlD2tWVfxnemkCGk0/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/65121235/fatal-error-lifecycleowners-must-call-register-before-they-are-started-on-regist&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://stackoverflow.com/questions/65121235/fatal-error-lifecycleowners-must-call-register-before-they-are-started-on-regist&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/J6WVl/hyKnqljy96/DGVIBjlD2tWVfxnemkCGk0/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Fatal error LifecycleOwners must call register before they are STARTED on registerForActivityResult&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;I have a simple empty activity that checks if permissions need to be requested. When registerForActivityResult is called, it crashes with the error java.lang.IllegalStateException: LifecycleOwner com.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;stackoverflow.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>Android/Kotlin</category>
      <category>Android</category>
      <category>Kotlin</category>
      <category>registerForActivityResult</category>
      <category>안드로이드</category>
      <category>코틀린</category>
      <author>혀가 길지 않은 개발자</author>
      <guid isPermaLink="true">https://jwsoft91.tistory.com/278</guid>
      <comments>https://jwsoft91.tistory.com/278#entry278comment</comments>
      <pubDate>Thu, 27 May 2021 21:01:07 +0900</pubDate>
    </item>
    <item>
      <title>[Kotlin]&amp;nbsp; 위치 권한</title>
      <link>https://jwsoft91.tistory.com/277</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 위치 권한 팝업 (2가지) (&lt;span style=&quot;color: #ee2323;&quot;&gt;주의사항&lt;/span&gt;)&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. GPS 허용 팝업, 위치 얻기&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Manifest.permission.&lt;span style=&quot;color: #9876aa;&quot;&gt;ACCESS_FINE_LOCATION &lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;(해당 권한 팝업 허용시 &lt;/span&gt;&lt;span style=&quot;color: #9876aa;&quot;&gt;ACCESS_COARSE_LOCATION&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;&amp;nbsp;권한도 허용됨)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9876aa;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Manifest.permission.&lt;/span&gt;ACCESS_COARSE_LOCATION &lt;span style=&quot;color: #333333;&quot;&gt;(팝업 허용시 &lt;span style=&quot;color: #9876aa;&quot;&gt;ACCESS_FINE_LOCATION&lt;/span&gt;&amp;nbsp;권한은 허용이 안됨)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ContextCompat.checkSelfPermission()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ActivityResultContracts.RequestPermission()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ActivityResultContracts.RequestMultiplePermissions()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PackageManager.&lt;span style=&quot;color: #9876aa;&quot;&gt;PERMISSION_GRANTED&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;checkSelfPermission&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;requestPermissions&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;FusedLocationProviderApi&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FusedLocationProviderClient&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 위치 권한 팝업 (2가지) (&lt;span style=&quot;color: #ee2323;&quot;&gt;주의사항&lt;/span&gt;)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;activity_main.xml&lt;/p&gt;
&lt;pre id=&quot;code_1622352810830&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    android:orientation=&quot;vertical&quot;
    android:gravity=&quot;center&quot;
    tools:context=&quot;.MainActivity&quot;&amp;gt;

    &amp;lt;TextView
        android:id=&quot;@+id/tv_latitude&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:textSize=&quot;24dp&quot;
        tools:text=&quot;111.12313&quot;/&amp;gt;

    &amp;lt;TextView
        android:id=&quot;@+id/tv_longitude&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:textSize=&quot;24dp&quot;
        tools:text=&quot;122.244231&quot;/&amp;gt;

    &amp;lt;androidx.appcompat.widget.AppCompatButton
        android:id=&quot;@+id/bt_permission_1&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_marginTop=&quot;20dp&quot;
        android:text=&quot;권한 요청 첫 번째 방법&quot;
        android:textAllCaps=&quot;false&quot; /&amp;gt;

    &amp;lt;androidx.appcompat.widget.AppCompatButton
        android:id=&quot;@+id/bt_permission_2&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:text=&quot;권한 요청 두 번째 방법&quot;
        android:textAllCaps=&quot;false&quot; /&amp;gt;

&amp;lt;/LinearLayout&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1642&quot; data-origin-height=&quot;1384&quot; data-filename=&quot;스크린샷 2021-05-30 오후 2.33.41.png&quot; width=&quot;491&quot; height=&quot;414&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8gerW/btq56c8N7sF/1ra3SVcAhjMedHM4YIkW61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8gerW/btq56c8N7sF/1ra3SVcAhjMedHM4YIkW61/img.png&quot; data-alt=&quot;activity_main.xml&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8gerW/btq56c8N7sF/1ra3SVcAhjMedHM4YIkW61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8gerW%2Fbtq56c8N7sF%2F1ra3SVcAhjMedHM4YIkW61%2Fimg.png&quot; data-origin-width=&quot;1642&quot; data-origin-height=&quot;1384&quot; data-filename=&quot;스크린샷 2021-05-30 오후 2.33.41.png&quot; width=&quot;491&quot; height=&quot;414&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;activity_main.xml&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MainActivity.kt&lt;/p&gt;
&lt;pre id=&quot;code_1622352854877&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.example.gpsexample

import android.Manifest
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatButton
import androidx.core.content.ContextCompat

/**
 * 1. ActivityResultLauncher.launch() 를 이용하여 위치 권한 요청
 * 2. Activity.RequestPermissions() 를 이용하여 위치 권한 요청
 *
 * 주의 사항 : 첫 번째 방법 사용 시 onRequestPermissionsResult() 의 super() 먼저 호출되고
 *          registerForActivityResult 콜백이 실행된 후 다시
 *          onRequestPermissionsResult() super() 하위 코드가 실행된다.
 *          when() 으로 분기 처리 안 하면 위치 권한 응답 처리가 두 번 된다.
 *
 *          두 번째 방법 사용 시엔 onRequestPermissionsResult() 만 실행됨.
 *
 *          즉, 사용자가 시스템 권한 대화상자에 응답하면 onRequestPermissionsResult() 실행됨.
 */
class MainActivity : AppCompatActivity() {

    companion object {
        const val REQUEST_CODE_PERMISSIONS = 1001
    }

    private val permissions = arrayOf(
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.ACCESS_COARSE_LOCATION
    )

    private val tvLatitude: TextView by lazy { findViewById(R.id.tv_latitude) }
    private val tvLongitude: TextView by lazy { findViewById(R.id.tv_longitude) }
    private val btPermission1: AppCompatButton by lazy { findViewById(R.id.bt_permission_1) }
    private val btPermission2: AppCompatButton by lazy { findViewById(R.id.bt_permission_2) }

    private lateinit var activityResultLauncher: ActivityResultLauncher&amp;lt;Array&amp;lt;String&amp;gt;&amp;gt;

    @RequiresApi(Build.VERSION_CODES.M)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        activityResultLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
            if (it.all { permission -&amp;gt; permission.value == true }) {

            } else {
                Toast.makeText(this, &quot;권한 거부&quot;, Toast.LENGTH_SHORT).show()
            }
        }

        setOnClick()
    }

    /**
     * 버튼 클릭 이벤트
     */
    @RequiresApi(Build.VERSION_CODES.M)
    private fun setOnClick() {

        // 권한 요청 첫 번째 방법
        btPermission1.setOnClickListener {
            if (checkPermission(permissions)) {
                activityResultLauncher.launch(permissions)
            }
        }

        // 권한 요청 두 번째 방법
        btPermission2.setOnClickListener {
            if (!checkPermission(permissions)) {
                requestPermissions(permissions, REQUEST_CODE_PERMISSIONS)
            }
        }
    }

    /**
     * 권한 체크
     */
    private fun checkPermission(permissions: Array&amp;lt;String&amp;gt;): Boolean {
        return permissions.all {
            ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
        }
    }

    /**
     * 권한 요청 결과
     */
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array&amp;lt;out String&amp;gt;,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            REQUEST_CODE_PERMISSIONS -&amp;gt; {
                if (grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {

                } else {
                    Toast.makeText(this, &quot;권한 거부&quot;, Toast.LENGTH_SHORT).show()
                }
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Activity.RequestPermissions() 사용시 &lt;span style=&quot;color: #bbb529;&quot;&gt;@RequiresApi&lt;/span&gt;(Build.VERSION_CODES.&lt;span style=&quot;color: #9876aa;&quot;&gt;M&lt;/span&gt;) 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, ActivityResultLauncher 사용 &lt;span style=&quot;color: #009a87;&quot;&gt;추천&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;주의사항&lt;/span&gt; :&amp;nbsp;&lt;span style=&quot;color: #333333;&quot;&gt;둘 다 onRequestPermissionResult 호출됨. (when 분기처리 한 이유)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;806&quot; data-origin-height=&quot;1738&quot; height=&quot;562&quot; data-filename=&quot;2021-05-30 15.10.15.gif&quot; width=&quot;261&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tBmMo/btq52Ai1chW/Z5GLZ1ezcZtVK9TXgQDfO1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tBmMo/btq52Ai1chW/Z5GLZ1ezcZtVK9TXgQDfO1/img.gif&quot; data-alt=&quot;실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tBmMo/btq52Ai1chW/Z5GLZ1ezcZtVK9TXgQDfO1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/tBmMo/btq52Ai1chW/Z5GLZ1ezcZtVK9TXgQDfO1/img.gif&quot; data-origin-width=&quot;806&quot; data-origin-height=&quot;1738&quot; height=&quot;562&quot; data-filename=&quot;2021-05-30 15.10.15.gif&quot; width=&quot;261&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. GPS 허용 팝업, 위치 얻기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LocationRequest&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LocationSettingRequest&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FusedLocationProviderClient&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LocationCallback()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ActivityResultContracts.StartIntentSenderForResult()&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;activity_main.xml&lt;/p&gt;
&lt;pre id=&quot;code_1622363593291&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    android:orientation=&quot;vertical&quot;
    android:gravity=&quot;center&quot;
    tools:context=&quot;.MainActivity&quot;&amp;gt;

    &amp;lt;TextView
        android:id=&quot;@+id/tv_latitude&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:textSize=&quot;24dp&quot;
        tools:text=&quot;111.12313&quot;/&amp;gt;

    &amp;lt;TextView
        android:id=&quot;@+id/tv_longitude&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:textSize=&quot;24dp&quot;
        tools:text=&quot;122.244231&quot;/&amp;gt;

    &amp;lt;androidx.appcompat.widget.AppCompatButton
        android:id=&quot;@+id/bt_permission_1&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_marginTop=&quot;20dp&quot;
        android:text=&quot;권한 요청 첫 번째 방법&quot;
        android:textAllCaps=&quot;false&quot; /&amp;gt;

    &amp;lt;androidx.appcompat.widget.AppCompatButton
        android:id=&quot;@+id/bt_permission_2&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:text=&quot;권한 요청 두 번째 방법&quot;
        android:textAllCaps=&quot;false&quot; /&amp;gt;

    &amp;lt;androidx.appcompat.widget.AppCompatButton
        android:id=&quot;@+id/bt_location&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:text=&quot;위치 얻기&quot;
        android:textAllCaps=&quot;false&quot; /&amp;gt;

&amp;lt;/LinearLayout&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1642&quot; data-origin-height=&quot;1380&quot; data-filename=&quot;스크린샷 2021-05-30 오후 5.33.24.png&quot; width=&quot;433&quot; height=&quot;364&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bc2PdF/btq6aOe8dgp/On0j05wl399OvvtOVP8861/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bc2PdF/btq6aOe8dgp/On0j05wl399OvvtOVP8861/img.png&quot; data-alt=&quot;activity_main.xml&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bc2PdF/btq6aOe8dgp/On0j05wl399OvvtOVP8861/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbc2PdF%2Fbtq6aOe8dgp%2FOn0j05wl399OvvtOVP8861%2Fimg.png&quot; data-origin-width=&quot;1642&quot; data-origin-height=&quot;1380&quot; data-filename=&quot;스크린샷 2021-05-30 오후 5.33.24.png&quot; width=&quot;433&quot; height=&quot;364&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;activity_main.xml&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MainActivity.kt&lt;/p&gt;
&lt;pre id=&quot;code_1622363631716&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.example.gpsexample

import android.Manifest
import android.annotation.SuppressLint
import android.content.Intent
import android.content.IntentSender
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.os.Looper
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.IntentSenderRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatButton
import androidx.core.content.ContextCompat
import com.google.android.gms.common.api.ResolvableApiException
import com.google.android.gms.location.*

/**
 * 1. ActivityResultLauncher.launch() 를 이용하여 위치 권한 요청
 * 2. Activity.RequestPermissions() 를 이용하여 위치 권한 요청
 *
 * 주의 사항 : 첫 번째 방법 사용 시 onRequestPermissionsResult() 의 super() 먼저 호출되고
 *          registerForActivityResult 콜백이 실행된 후 다시
 *          onRequestPermissionsResult() super() 하위 코드가 실행된다.
 *          when() 으로 분기 처리 안 하면 위치 권한 응답 처리가 두 번 된다.
 *
 *          두 번째 방법 사용 시엔 onRequestPermissionsResult() 만 실행됨.
 *
 *          즉, 사용자가 시스템 권한 대화상자에 응답하면 onRequestPermissionsResult() 실행됨.
 */
class MainActivity : AppCompatActivity() {

    companion object {
        const val REQUEST_CODE_PERMISSIONS = 1001
    }

    private val permissions = arrayOf(
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.ACCESS_COARSE_LOCATION
    )

    private val tvLatitude: TextView by lazy { findViewById(R.id.tv_latitude) }
    private val tvLongitude: TextView by lazy { findViewById(R.id.tv_longitude) }
    private val btPermission1: AppCompatButton by lazy { findViewById(R.id.bt_permission_1) }
    private val btPermission2: AppCompatButton by lazy { findViewById(R.id.bt_permission_2) }
    private val btLocation: AppCompatButton by lazy { findViewById(R.id.bt_location) }

    private lateinit var permissionResultLauncher: ActivityResultLauncher&amp;lt;Array&amp;lt;String&amp;gt;&amp;gt;
    private lateinit var resolutionResultLauncher: ActivityResultLauncher&amp;lt;IntentSenderRequest&amp;gt;

    private val locationRequest = LocationRequest.create().apply {
        priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        interval = 10000
        fastestInterval = 5000
        numUpdates = 10
    }

    private val builder = LocationSettingsRequest.Builder()
        .addLocationRequest(locationRequest)
        .setAlwaysShow(true)

    private lateinit var fusedLocationClient: FusedLocationProviderClient

    private val locationCallback = object : LocationCallback() {
        override fun onLocationResult(p0: LocationResult) {
            super.onLocationResult(p0)
            tvLatitude.text = p0.lastLocation.latitude.toString()
            tvLongitude.text = p0.lastLocation.longitude.toString()
        }

        override fun onLocationAvailability(p0: LocationAvailability) {
            super.onLocationAvailability(p0)
        }
    }

    @SuppressLint(&quot;VisibleForTests&quot;)
    @RequiresApi(Build.VERSION_CODES.M)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        fusedLocationClient = FusedLocationProviderClient(this)

        permissionResultLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
            if (it.all { permission -&amp;gt; permission.value == true }) {
                getLocation()
            } else {
                Toast.makeText(this, &quot;권한 거부&quot;, Toast.LENGTH_SHORT).show()
            }
        }

        resolutionResultLauncher = registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) {
            if (it.resultCode == RESULT_OK) {
                getLocation()
            }
        }

        setOnClick()
    }

    override fun onPause() {
        super.onPause()
        fusedLocationClient.removeLocationUpdates(locationCallback)
    }

    /**
     * 버튼 클릭 이벤트
     */
    @RequiresApi(Build.VERSION_CODES.M)
    private fun setOnClick() {
        // 권한 요청 첫 번째 방법
        btPermission1.setOnClickListener {
            if (!checkPermission(permissions)) {
                permissionResultLauncher.launch(permissions)
            } else {
                Toast.makeText(this, &quot;이미 권한이 있습니다.&quot;, Toast.LENGTH_SHORT).show()
            }
        }

        // 권한 요청 두 번째 방법
        btPermission2.setOnClickListener {
            if (!checkPermission(permissions)) {
                requestPermissions(permissions, REQUEST_CODE_PERMISSIONS)
            } else {
                Toast.makeText(this, &quot;이미 권한이 있습니다.&quot;, Toast.LENGTH_SHORT).show()
            }
        }

        // 위치 얻기
        btLocation.setOnClickListener {
            getLocation()
        }
    }

    /**
     * 권한 체크
     */
    private fun checkPermission(permissions: Array&amp;lt;String&amp;gt;): Boolean {
        return permissions.all {
            ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_GRANTED
        }
    }

    /**
     * 위치 얻기
     */
    private fun getLocation() {
        if (checkPermission(permissions)) {
            LocationServices.getSettingsClient(this@MainActivity).checkLocationSettings(builder.build()).run {
                addOnSuccessListener { response -&amp;gt;
                    // All location settings are satisfied. The client can initialize
                    // location requests here.
                    // ...
                    fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
                }

                addOnFailureListener { exception -&amp;gt;
                    if (exception is ResolvableApiException) {
                        // Location settings are not satisfied, but this can be fixed
                        // by showing the user a dialog.
                        try {
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            val intentSenderRequest = IntentSenderRequest.Builder(exception.resolution).build()
                            resolutionResultLauncher.launch(intentSenderRequest)
                        } catch (sendEx: IntentSender.SendIntentException) {
                            // Ignore the error.
                        }
                    }
                }
            }
        } else {
            permissionResultLauncher.launch(permissions)
        }
    }

    /**
     * 권한 요청 결과
     */
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array&amp;lt;out String&amp;gt;,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            REQUEST_CODE_PERMISSIONS -&amp;gt; {
                if (grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {

                } else {
                    Toast.makeText(this, &quot;권한 거부&quot;, Toast.LENGTH_SHORT).show()
                }
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;818&quot; data-origin-height=&quot;1752&quot; data-filename=&quot;스크린샷 2021-05-30 오후 5.52.41.png&quot; width=&quot;266&quot; height=&quot;569&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFg7qz/btq54n3YEIn/sbSctYRkqSZupxUKjhxBK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFg7qz/btq54n3YEIn/sbSctYRkqSZupxUKjhxBK0/img.png&quot; data-alt=&quot;시스템 위치 OFF 상태&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFg7qz/btq54n3YEIn/sbSctYRkqSZupxUKjhxBK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFg7qz%2Fbtq54n3YEIn%2FsbSctYRkqSZupxUKjhxBK0%2Fimg.png&quot; data-origin-width=&quot;818&quot; data-origin-height=&quot;1752&quot; data-filename=&quot;스크린샷 2021-05-30 오후 5.52.41.png&quot; width=&quot;266&quot; height=&quot;569&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;시스템 위치 OFF 상태&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;804&quot; data-origin-height=&quot;1752&quot; data-filename=&quot;2021-05-30 17.53.29.gif&quot; width=&quot;269&quot; height=&quot;586&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTn9II/btq6b1ejGJq/KKpEKezaMC6i1xPesPXQg1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTn9II/btq6b1ejGJq/KKpEKezaMC6i1xPesPXQg1/img.gif&quot; data-alt=&quot;실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTn9II/btq6b1ejGJq/KKpEKezaMC6i1xPesPXQg1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bTn9II/btq6b1ejGJq/KKpEKezaMC6i1xPesPXQg1/img.gif&quot; data-origin-width=&quot;804&quot; data-origin-height=&quot;1752&quot; data-filename=&quot;2021-05-30 17.53.29.gif&quot; width=&quot;269&quot; height=&quot;586&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;812&quot; data-origin-height=&quot;1756&quot; data-filename=&quot;스크린샷 2021-05-30 오후 5.55.56.png&quot; width=&quot;265&quot; height=&quot;573&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IJQjP/btq52ApREY3/KTlJk4ro4akrL8hZAlV411/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IJQjP/btq52ApREY3/KTlJk4ro4akrL8hZAlV411/img.png&quot; data-alt=&quot;위치 사용 ON 상태&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IJQjP/btq52ApREY3/KTlJk4ro4akrL8hZAlV411/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIJQjP%2Fbtq52ApREY3%2FKTlJk4ro4akrL8hZAlV411%2Fimg.png&quot; data-origin-width=&quot;812&quot; data-origin-height=&quot;1756&quot; data-filename=&quot;스크린샷 2021-05-30 오후 5.55.56.png&quot; width=&quot;265&quot; height=&quot;573&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;위치 사용 ON 상태&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.android.com/training/location/change-location-settings?hl=ko&quot;&gt;https://developer.android.com/training/location/change-location-settings?hl=ko&lt;/a&gt; (위치 요청 다이얼로그)&lt;/p&gt;
&lt;figure id=&quot;og_1622355464204&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;위치 설정 변경 &amp;nbsp;|&amp;nbsp; Android 개발자 &amp;nbsp;|&amp;nbsp; Android Developers&quot; data-og-description=&quot;앱에서 위치를 요청하거나 권한 업데이트를 수신해야 한다면 기기는 GPS 또는 Wi-Fi 검색과 같은 적절한 시스템 설정을 사용해야 합니다. 앱은 서비스(예: 기기의 GPS)를 직접 사용 설정하기보다는 &quot; data-og-host=&quot;developer.android.com&quot; data-og-source-url=&quot;https://developer.android.com/training/location/change-location-settings?hl=ko&quot; data-og-url=&quot;https://developer.android.com/training/location/change-location-settings?hl=ko&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Q7suZ/hyKnhpuqEn/sTxbdzEdWcKn6H2jRkmg70/img.png?width=1201&amp;amp;height=676&amp;amp;face=0_0_1201_676&quot;&gt;&lt;a href=&quot;https://developer.android.com/training/location/change-location-settings?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.android.com/training/location/change-location-settings?hl=ko&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Q7suZ/hyKnhpuqEn/sTxbdzEdWcKn6H2jRkmg70/img.png?width=1201&amp;amp;height=676&amp;amp;face=0_0_1201_676');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;위치 설정 변경 &amp;nbsp;|&amp;nbsp; Android 개발자 &amp;nbsp;|&amp;nbsp; Android Developers&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;앱에서 위치를 요청하거나 권한 업데이트를 수신해야 한다면 기기는 GPS 또는 Wi-Fi 검색과 같은 적절한 시스템 설정을 사용해야 합니다. 앱은 서비스(예: 기기의 GPS)를 직접 사용 설정하기보다는&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.android.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.android.com/training/location/request-updates?hl=ko#stop-updates&quot;&gt;https://developer.android.com/training/location/request-updates?hl=ko#stop-updates&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1622363566580&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;위치 업데이트 요청 &amp;nbsp;|&amp;nbsp; Android 개발자 &amp;nbsp;|&amp;nbsp; Android Developers&quot; data-og-description=&quot;위치 정보를 적절하게 사용하면 앱 사용자에게 도움이 될 수 있습니다. 예를 들어 사용자가 걷거나 운전하는 동안 길을 찾아주는 앱 또는 애셋의 위치를 추적하는 앱은 일정한 간격으로 기기의 &quot; data-og-host=&quot;developer.android.com&quot; data-og-source-url=&quot;https://developer.android.com/training/location/request-updates?hl=ko#stop-updates&quot; data-og-url=&quot;https://developer.android.com/training/location/request-updates?hl=ko&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bVtp72/hyKoYu8Su3/Gbqh7Mkgnwxq7LIOwC6RiK/img.png?width=1201&amp;amp;height=676&amp;amp;face=0_0_1201_676&quot;&gt;&lt;a href=&quot;https://developer.android.com/training/location/request-updates?hl=ko#stop-updates&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.android.com/training/location/request-updates?hl=ko#stop-updates&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bVtp72/hyKoYu8Su3/Gbqh7Mkgnwxq7LIOwC6RiK/img.png?width=1201&amp;amp;height=676&amp;amp;face=0_0_1201_676');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;위치 업데이트 요청 &amp;nbsp;|&amp;nbsp; Android 개발자 &amp;nbsp;|&amp;nbsp; Android Developers&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;위치 정보를 적절하게 사용하면 앱 사용자에게 도움이 될 수 있습니다. 예를 들어 사용자가 걷거나 운전하는 동안 길을 찾아주는 앱 또는 애셋의 위치를 추적하는 앱은 일정한 간격으로 기기의&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.android.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/65158308/deprecated-onactivityresult-in-androidx&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://stackoverflow.com/questions/65158308/deprecated-onactivityresult-in-androidx&lt;/a&gt; &amp;nbsp;(startResolutionForResult 응답 처리)&lt;/p&gt;
&lt;figure id=&quot;og_1622364466868&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;deprecated OnActivityResult() in androidx&quot; data-og-description=&quot;OnActivityResult() is deprecated in androidx. I took reference from below links https://developer.android.com/training/basics/intents/result https://developer.android.com/jetpack/androidx/releases/&quot; data-og-host=&quot;stackoverflow.com&quot; data-og-source-url=&quot;https://stackoverflow.com/questions/65158308/deprecated-onactivityresult-in-androidx&quot; data-og-url=&quot;https://stackoverflow.com/questions/65158308/deprecated-onactivityresult-in-androidx&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bitOm0/hyKo00NUN2/pyiNN9asxVnnp6o0FMvaNk/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/65158308/deprecated-onactivityresult-in-androidx&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://stackoverflow.com/questions/65158308/deprecated-onactivityresult-in-androidx&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bitOm0/hyKo00NUN2/pyiNN9asxVnnp6o0FMvaNk/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;deprecated OnActivityResult() in androidx&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;OnActivityResult() is deprecated in androidx. I took reference from below links https://developer.android.com/training/basics/intents/result https://developer.android.com/jetpack/androidx/releases/&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;stackoverflow.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android/Kotlin</category>
      <category>Android</category>
      <category>Kotlin</category>
      <category>permission</category>
      <category>안드로이드</category>
      <category>코틀린</category>
      <author>혀가 길지 않은 개발자</author>
      <guid isPermaLink="true">https://jwsoft91.tistory.com/277</guid>
      <comments>https://jwsoft91.tistory.com/277#entry277comment</comments>
      <pubDate>Thu, 27 May 2021 04:32:57 +0900</pubDate>
    </item>
    <item>
      <title>[Kotlin]&amp;nbsp; View</title>
      <link>https://jwsoft91.tistory.com/276</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Widget&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Layout&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;requestLayout()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;invalidate()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Button&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EditText&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TextView&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LinearLayout&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Toolbar&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ViewGroup&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;View&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1418&quot; data-origin-height=&quot;1246&quot; data-filename=&quot;스크린샷 2021-05-25 오후 11.41.15.png&quot; width=&quot;656&quot; height=&quot;576&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VqWoU/btq5HMwA8Nq/uFxL4phC2eZeKH9y3jTH7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VqWoU/btq5HMwA8Nq/uFxL4phC2eZeKH9y3jTH7K/img.png&quot; data-alt=&quot;View Lifecycle&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VqWoU/btq5HMwA8Nq/uFxL4phC2eZeKH9y3jTH7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVqWoU%2Fbtq5HMwA8Nq%2FuFxL4phC2eZeKH9y3jTH7K%2Fimg.png&quot; data-origin-width=&quot;1418&quot; data-origin-height=&quot;1246&quot; data-filename=&quot;스크린샷 2021-05-25 오후 11.41.15.png&quot; width=&quot;656&quot; height=&quot;576&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;View Lifecycle&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.charlezz.com/?p=29013&quot;&gt;https://www.charlezz.com/?p=29013&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1621953755124&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Android에서 View의 생명주기 | 찰스의 안드로이드&quot; data-og-description=&quot;https://proandroiddev.com/the-life-cycle-of-a-view-in-android-6a2c4665b95e을 번역한 내용입니다. 안드로이드 앱을 실행할 때 우리가 가장 먼저 스크린에서 볼 수 있는 것이 View라고 말할 수 있다. View 클래스는 사&quot; data-og-host=&quot;www.charlezz.com&quot; data-og-source-url=&quot;https://www.charlezz.com/?p=29013&quot; data-og-url=&quot;https://www.charlezz.com/?p=29013&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ppKn7/hyKlmwC9r9/e4a1m367efDEGOcNS07yF0/img.png?width=1365&amp;amp;height=1179&amp;amp;face=0_0_1365_1179,https://scrap.kakaocdn.net/dn/seTjJ/hyKlkyPDU8/I5yYJPyCCWNxhps9dB6F11/img.png?width=516&amp;amp;height=716&amp;amp;face=0_0_516_716,https://scrap.kakaocdn.net/dn/bVnwlZ/hyKk8LUv5z/MkMC7qcRQo8q5WrkD8Ll41/img.png?width=1600&amp;amp;height=200&amp;amp;face=0_0_1600_200&quot;&gt;&lt;a href=&quot;https://www.charlezz.com/?p=29013&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.charlezz.com/?p=29013&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ppKn7/hyKlmwC9r9/e4a1m367efDEGOcNS07yF0/img.png?width=1365&amp;amp;height=1179&amp;amp;face=0_0_1365_1179,https://scrap.kakaocdn.net/dn/seTjJ/hyKlkyPDU8/I5yYJPyCCWNxhps9dB6F11/img.png?width=516&amp;amp;height=716&amp;amp;face=0_0_516_716,https://scrap.kakaocdn.net/dn/bVnwlZ/hyKk8LUv5z/MkMC7qcRQo8q5WrkD8Ll41/img.png?width=1600&amp;amp;height=200&amp;amp;face=0_0_1600_200');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Android에서 View의 생명주기 | 찰스의 안드로이드&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;https://proandroiddev.com/the-life-cycle-of-a-view-in-android-6a2c4665b95e을 번역한 내용입니다. 안드로이드 앱을 실행할 때 우리가 가장 먼저 스크린에서 볼 수 있는 것이 View라고 말할 수 있다. View 클래스는 사&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.charlezz.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android/Kotlin</category>
      <category>Android</category>
      <category>Kotlin</category>
      <category>View</category>
      <category>안드로이드</category>
      <category>코틀린</category>
      <author>혀가 길지 않은 개발자</author>
      <guid isPermaLink="true">https://jwsoft91.tistory.com/276</guid>
      <comments>https://jwsoft91.tistory.com/276#entry276comment</comments>
      <pubDate>Tue, 25 May 2021 23:34:37 +0900</pubDate>
    </item>
    <item>
      <title>[Kotlin]  dp와 px</title>
      <link>https://jwsoft91.tistory.com/275</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;dp와 px 지긋지긋하다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;px : 화면을 구성하는 최소 단위 (px = dp * dpi / 160)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DPI : 1인치에 들어가는 px을 나타내는 단위 (&lt;span style=&quot;color: #000000;&quot;&gt;Dot Per Inch) (100dpi = 1인치에 100px)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;dp : 픽셀 독립 단위 (dp = px * 160 / dpi)&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ldpi : 120dpi&lt;/li&gt;
&lt;li&gt;mdpi : 160dpi (기본) (1dp = 1px)&lt;/li&gt;
&lt;li&gt;hdpi : 240dpi&lt;/li&gt;
&lt;li&gt;xhdpi : 320dpi&lt;/li&gt;
&lt;li&gt;xxhdpi : 480dpi&lt;/li&gt;
&lt;li&gt;xxxhdpi : 640dpi&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;1486&quot; data-filename=&quot;스크린샷 2021-05-25 오후 8.46.49.png&quot; width=&quot;245&quot; height=&quot;478&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mSlpb/btq5MuBCzNr/A2yhxFdVKLAAUThQXF46iK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mSlpb/btq5MuBCzNr/A2yhxFdVKLAAUThQXF46iK/img.png&quot; data-alt=&quot;hdpi&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mSlpb/btq5MuBCzNr/A2yhxFdVKLAAUThQXF46iK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmSlpb%2Fbtq5MuBCzNr%2FA2yhxFdVKLAAUThQXF46iK%2Fimg.png&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;1486&quot; data-filename=&quot;스크린샷 2021-05-25 오후 8.46.49.png&quot; width=&quot;245&quot; height=&quot;478&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;hdpi&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;dpi : 240&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ImageView 사이즈 : 400px / 400px&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TextView 사이즈 : 100px&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;648&quot; data-origin-height=&quot;1364&quot; data-filename=&quot;스크린샷 2021-05-25 오후 8.47.28.png&quot; width=&quot;265&quot; height=&quot;557&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpD45y/btq5Mon0iIG/Hv0RPDt39VdqMCe1Yzh3mk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpD45y/btq5Mon0iIG/Hv0RPDt39VdqMCe1Yzh3mk/img.png&quot; data-alt=&quot;440dpi&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpD45y/btq5Mon0iIG/Hv0RPDt39VdqMCe1Yzh3mk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpD45y%2Fbtq5Mon0iIG%2FHv0RPDt39VdqMCe1Yzh3mk%2Fimg.png&quot; data-origin-width=&quot;648&quot; data-origin-height=&quot;1364&quot; data-filename=&quot;스크린샷 2021-05-25 오후 8.47.28.png&quot; width=&quot;265&quot; height=&quot;557&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;440dpi&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;dpi : 440&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ImageView 사이즈 : 400px / 400px&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TextView 사이즈 : 100px&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이래서 dp를 사용하는 게 좋다. dp로 설정했을 때 차이를 보자.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;1474&quot; data-filename=&quot;스크린샷 2021-05-25 오후 8.52.55.png&quot; width=&quot;270&quot; height=&quot;519&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KYG2D/btq5Gduy2Pg/4jf9h7KPtmp463mm37vbK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KYG2D/btq5Gduy2Pg/4jf9h7KPtmp463mm37vbK1/img.png&quot; data-alt=&quot;hdpi&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KYG2D/btq5Gduy2Pg/4jf9h7KPtmp463mm37vbK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKYG2D%2Fbtq5Gduy2Pg%2F4jf9h7KPtmp463mm37vbK1%2Fimg.png&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;1474&quot; data-filename=&quot;스크린샷 2021-05-25 오후 8.52.55.png&quot; width=&quot;270&quot; height=&quot;519&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;hdpi&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;dpi : 240&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ImageView 사이즈 : 200dp / 200dp&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TextView 사이즈 : 40dp&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;1356&quot; data-filename=&quot;스크린샷 2021-05-25 오후 8.53.46.png&quot; width=&quot;270&quot; height=&quot;564&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/muIst/btq5FTDbfcJ/byxjmLsT18Sus0qsXi2uIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/muIst/btq5FTDbfcJ/byxjmLsT18Sus0qsXi2uIK/img.png&quot; data-alt=&quot;440dpi&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/muIst/btq5FTDbfcJ/byxjmLsT18Sus0qsXi2uIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmuIst%2Fbtq5FTDbfcJ%2FbyxjmLsT18Sus0qsXi2uIK%2Fimg.png&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;1356&quot; data-filename=&quot;스크린샷 2021-05-25 오후 8.53.46.png&quot; width=&quot;270&quot; height=&quot;564&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;440dpi&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;dpi : 440&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ImageView 사이즈 : 200dp / 200dp&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TextView 사이즈 : 40dp&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이래서 dp를 사용하는 게 좋다. 비율이 맞다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;dp 와 px 간 변환&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Resources.getSystem().displayMetrics.density (dpi / 160)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;dp &amp;lt;-&amp;gt; px 둘 다 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TypedValue.applyDimension(TypedValue.&lt;span style=&quot;color: #9876aa;&quot;&gt;COMPLEX_UNIT_DIP&lt;/span&gt;&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;dp&lt;span style=&quot;color: #cc7832;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #9876aa;&quot;&gt;resources&lt;/span&gt;.&lt;span style=&quot;color: #9876aa;&quot;&gt;displayMetrics&lt;/span&gt;).&lt;span style=&quot;color: #ffc66d;&quot;&gt;roundToInt&lt;/span&gt;()&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;얘는 dp To px 만 가능.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android/Kotlin</category>
      <category>Android</category>
      <category>DP</category>
      <category>Kotlin</category>
      <category>PX</category>
      <category>안드로이드</category>
      <category>코틀린</category>
      <author>혀가 길지 않은 개발자</author>
      <guid isPermaLink="true">https://jwsoft91.tistory.com/275</guid>
      <comments>https://jwsoft91.tistory.com/275#entry275comment</comments>
      <pubDate>Tue, 25 May 2021 20:54:32 +0900</pubDate>
    </item>
    <item>
      <title>[Kotlin] CoordinatorLayout</title>
      <link>https://jwsoft91.tistory.com/273</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CoordinatorLayout&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AppBarLayout&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MaterialToolbar&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;app:layout_scrollFlags&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;app:layout_behavior=&quot;@string/appbar_scrolling_view_behavior&quot;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;fragment_plant_detail.xml&lt;/p&gt;
&lt;pre id=&quot;code_1621823202843&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;layout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;&amp;gt;

    &amp;lt;androidx.coordinatorlayout.widget.CoordinatorLayout
        android:id=&quot;@+id/cnl_&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;match_parent&quot;
        android:fitsSystemWindows=&quot;true&quot;&amp;gt;

        &amp;lt;com.google.android.material.appbar.AppBarLayout
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;wrap_content&quot;&amp;gt;

            &amp;lt;com.google.android.material.appbar.MaterialToolbar
                android:layout_width=&quot;match_parent&quot;
                android:layout_height=&quot;wrap_content&quot;
                app:layout_scrollFlags=&quot;scroll|enterAlways&quot;
                app:title=&quot;@string/app_name&quot; /&amp;gt;

        &amp;lt;/com.google.android.material.appbar.AppBarLayout&amp;gt;

        &amp;lt;androidx.core.widget.NestedScrollView
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;match_parent&quot;
            app:layout_behavior=&quot;@string/appbar_scrolling_view_behavior&quot;&amp;gt;

            &amp;lt;LinearLayout
                android:layout_width=&quot;match_parent&quot;
                android:layout_height=&quot;match_parent&quot;
                android:orientation=&quot;vertical&quot;&amp;gt;

                &amp;lt;TextView
                    android:layout_width=&quot;match_parent&quot;
                    android:layout_height=&quot;800dp&quot;
                    android:gravity=&quot;center&quot;
                    android:text=&quot;1&quot;
                    android:textSize=&quot;30sp&quot; /&amp;gt;

                &amp;lt;TextView
                    android:layout_width=&quot;match_parent&quot;
                    android:layout_height=&quot;800dp&quot;
                    android:gravity=&quot;center&quot;
                    android:text=&quot;2&quot;
                    android:textSize=&quot;30sp&quot; /&amp;gt;

                &amp;lt;TextView
                    android:layout_width=&quot;match_parent&quot;
                    android:layout_height=&quot;800dp&quot;
                    android:gravity=&quot;center&quot;
                    android:text=&quot;3&quot;
                    android:textSize=&quot;30sp&quot; /&amp;gt;

            &amp;lt;/LinearLayout&amp;gt;

        &amp;lt;/androidx.core.widget.NestedScrollView&amp;gt;

    &amp;lt;/androidx.coordinatorlayout.widget.CoordinatorLayout&amp;gt;

&amp;lt;/layout&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;1254&quot; data-filename=&quot;스크린샷 2021-05-24 오전 11.42.21.png&quot; width=&quot;435&quot; height=&quot;454&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccRfwM/btq5FhPwPCy/do8j0WjwM4LX1b7PL5na2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccRfwM/btq5FhPwPCy/do8j0WjwM4LX1b7PL5na2k/img.png&quot; data-alt=&quot;fragment_plant_detail.xml&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccRfwM/btq5FhPwPCy/do8j0WjwM4LX1b7PL5na2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccRfwM%2Fbtq5FhPwPCy%2Fdo8j0WjwM4LX1b7PL5na2k%2Fimg.png&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;1254&quot; data-filename=&quot;스크린샷 2021-05-24 오전 11.42.21.png&quot; width=&quot;435&quot; height=&quot;454&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;fragment_plant_detail.xml&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;app:layout_scrollFlags&lt;/b&gt; 의 종류&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;app:layout_scrollFlags=&quot;scroll|enterAlways&quot; (스크롤 내리면 툴바 노출, 스크롤 올리면 툴바 사라짐)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;1222&quot; data-filename=&quot;2021-05-24 11.44.12.gif&quot; width=&quot;226&quot; height=&quot;472&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cz98mi/btq5zFD55IJ/OfwfVuqyAyULoKHih5ClA0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cz98mi/btq5zFD55IJ/OfwfVuqyAyULoKHih5ClA0/img.gif&quot; data-alt=&quot;&amp;amp;quot;enterAlways&amp;amp;quot; 속성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cz98mi/btq5zFD55IJ/OfwfVuqyAyULoKHih5ClA0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/cz98mi/btq5zFD55IJ/OfwfVuqyAyULoKHih5ClA0/img.gif&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;1222&quot; data-filename=&quot;2021-05-24 11.44.12.gif&quot; width=&quot;226&quot; height=&quot;472&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&quot;enterAlways&quot; 속성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;app:layout_scrollFlags=&quot;scroll|&lt;span style=&quot;color: #333333;&quot;&gt;enterAlwaysCollapsed&lt;/span&gt;&quot; (스크롤 최상단까지 내리면 툴바 노출, 스크롤 올리면 툴바 사라짐)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;1210&quot; data-filename=&quot;2021-05-24 11.46.58.gif&quot; width=&quot;229&quot; height=&quot;480&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5jbKg/btq5wvIYJ9W/eDMzzjNHJt5Vy3phtn3t30/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5jbKg/btq5wvIYJ9W/eDMzzjNHJt5Vy3phtn3t30/img.gif&quot; data-alt=&quot;&amp;amp;quot;enterAlwaysCollapsed&amp;amp;quot; 속성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5jbKg/btq5wvIYJ9W/eDMzzjNHJt5Vy3phtn3t30/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/b5jbKg/btq5wvIYJ9W/eDMzzjNHJt5Vy3phtn3t30/img.gif&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;1210&quot; data-filename=&quot;2021-05-24 11.46.58.gif&quot; width=&quot;229&quot; height=&quot;480&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&quot;enterAlwaysCollapsed&quot; 속성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;app:layout_scrollFlags=&quot;scroll|&lt;span style=&quot;color: #333333;&quot;&gt;exitUntilCollapsed&lt;/span&gt;&quot; (반응 없음. CollapsingToolbarLayout 사용할 때 쓰임)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;1204&quot; data-filename=&quot;2021-05-24 11.50.10.gif&quot; width=&quot;242&quot; height=&quot;497&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnkTn4/btq5EsX169c/srmWDlXlCt07S3MCFXFuj1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnkTn4/btq5EsX169c/srmWDlXlCt07S3MCFXFuj1/img.gif&quot; data-alt=&quot;&amp;amp;quot;exitUntilCollapsed&amp;amp;quot; 속성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnkTn4/btq5EsX169c/srmWDlXlCt07S3MCFXFuj1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bnkTn4/btq5EsX169c/srmWDlXlCt07S3MCFXFuj1/img.gif&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;1204&quot; data-filename=&quot;2021-05-24 11.50.10.gif&quot; width=&quot;242&quot; height=&quot;497&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&quot;exitUntilCollapsed&quot; 속성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;app:layout_scrollFlags=&quot;scroll|snap&quot; (&quot;enterAlwaysCollapsed&quot;와 동일한 효과. CollapsingToolbarLayout 사용할 때 쓰임)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;229&quot; height=&quot;480&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;1210&quot; data-filename=&quot;2021-05-24 11.46.58.gif&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5jbKg/btq5wvIYJ9W/eDMzzjNHJt5Vy3phtn3t30/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5jbKg/btq5wvIYJ9W/eDMzzjNHJt5Vy3phtn3t30/img.gif&quot; data-alt=&quot;&amp;amp;quot;exitUntilCollapsed&amp;amp;quot; 속성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5jbKg/btq5wvIYJ9W/eDMzzjNHJt5Vy3phtn3t30/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/b5jbKg/btq5wvIYJ9W/eDMzzjNHJt5Vy3phtn3t30/img.gif&quot; width=&quot;229&quot; height=&quot;480&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;1210&quot; data-filename=&quot;2021-05-24 11.46.58.gif&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&quot;exitUntilCollapsed&quot; 속성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android/Kotlin</category>
      <category>Android</category>
      <category>CoordinatorLayout</category>
      <category>Kotlin</category>
      <category>안드로이드</category>
      <category>코틀린</category>
      <author>혀가 길지 않은 개발자</author>
      <guid isPermaLink="true">https://jwsoft91.tistory.com/273</guid>
      <comments>https://jwsoft91.tistory.com/273#entry273comment</comments>
      <pubDate>Mon, 24 May 2021 11:17:16 +0900</pubDate>
    </item>
    <item>
      <title>[Kotlin] CollapsingToolbarLayout</title>
      <link>https://jwsoft91.tistory.com/272</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CollapsingToolbarLayout&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Collapsing? 붕괴&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CoordinatorLayout&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AppBarLayout&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MaterialToolbar&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NestedScrollView&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FloatingActionButton&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9876aa;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: #bababa;&quot;&gt;:layout_height&lt;/span&gt;&lt;span style=&quot;color: #6a8759;&quot;&gt;=&quot;?attr/actionBarSize&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;fitsSystemWindows&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9876aa;&quot;&gt;app&lt;/span&gt;&lt;span style=&quot;color: #bababa;&quot;&gt;:contentInsetStart&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android/Kotlin</category>
      <category>Android</category>
      <category>CollapsingToolbarLayout</category>
      <category>Kotlin</category>
      <category>안드로이드</category>
      <category>코틀린</category>
      <author>혀가 길지 않은 개발자</author>
      <guid isPermaLink="true">https://jwsoft91.tistory.com/272</guid>
      <comments>https://jwsoft91.tistory.com/272#entry272comment</comments>
      <pubDate>Mon, 24 May 2021 00:27:18 +0900</pubDate>
    </item>
    <item>
      <title>[Kotlin] Navigation</title>
      <link>https://jwsoft91.tistory.com/271</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프레그먼트 간 이동을 관리&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FragmentContainerView&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nav_host&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;androidx.navigation.fragment.NavHostFragment&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;defaultNavHost&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;navGraph&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;build.gradle (Project)&lt;/p&gt;
&lt;pre id=&quot;code_1621780128648&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;buildscript {
    dependencies {
    	// safeArgs
        classpath &quot;android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0&quot;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;build.gradle (Module:app)&lt;/p&gt;
&lt;pre id=&quot;code_1621777963725&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;plugins {
    id 'dagger.hilt.android.plugin'             // hilt
    id 'androidx.navigation.safeargs.kotlin'	// safeArgs
}

dependencies {
    implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
    implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;activity_garden.xml&lt;/p&gt;
&lt;pre id=&quot;code_1621777517607&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;layout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;&amp;gt;

    &amp;lt;androidx.fragment.app.FragmentContainerView
        android:id=&quot;@+id/nav_host&quot;
        android:name=&quot;androidx.navigation.fragment.NavHostFragment&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;match_parent&quot;
        app:defaultNavHost=&quot;true&quot;
        app:navGraph=&quot;@navigation/nav_garden&quot; /&amp;gt;

&amp;lt;/layout&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GardenActivity.kt&lt;/p&gt;
&lt;pre id=&quot;code_1621781090956&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.example.sunflowerexample

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil.setContentView
import com.example.sunflowerexample.databinding.ActivityGardenBinding
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class GardenActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView&amp;lt;ActivityGardenBinding&amp;gt;(this, R.layout.activity_garden)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HomeViewPagerFragment.kt (xml에 버튼 하나 있음)&lt;/p&gt;
&lt;pre id=&quot;code_1621781151501&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.example.sunflowerexample

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.example.sunflowerexample.databinding.FragmentViewPagerBinding
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class HomeViewPagerFragment : Fragment() {

    lateinit var binding: FragmentViewPagerBinding

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentViewPagerBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.btViewPager.setOnClickListener {
            findNavController().navigate(HomeViewPagerFragmentDirections.actionViewPagerFragmentToPlantDetailFragment(&quot;plantId&quot;))
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PlantDetailFragment.kt (xml에 버튼 하나 있음)&lt;/p&gt;
&lt;pre id=&quot;code_1621781183142&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.example.sunflowerexample

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.example.sunflowerexample.databinding.FragmentPlantDetailBinding
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class PlantDetailFragment : Fragment() {

    lateinit var binding: FragmentPlantDetailBinding

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        binding = FragmentPlantDetailBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.btPlantDetail.setOnClickListener {
            findNavController().navigate(PlantDetailFragmentDirections.actionPlantDetailFragmentToGalleryFragment(&quot;plantName&quot;))
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GalleryFragment.kt (xml에 버튼 하나 있음)&lt;/p&gt;
&lt;pre id=&quot;code_1621781212821&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.example.sunflowerexample

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.example.sunflowerexample.databinding.FragmentGalleryBinding
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class GalleryFragment : Fragment()  {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val binding = FragmentGalleryBinding.inflate(inflater, container, false)
        return binding.root
    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nav_garden.xml&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1876&quot; data-origin-height=&quot;1362&quot; data-filename=&quot;스크린샷 2021-05-23 오후 10.48.35.png&quot; width=&quot;773&quot; height=&quot;561&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLnKQq/btq5u3rvS8b/F9I73Hx6kHePaPGwmD4uo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLnKQq/btq5u3rvS8b/F9I73Hx6kHePaPGwmD4uo1/img.png&quot; data-alt=&quot;nav_garden.xml 생성 절차 1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLnKQq/btq5u3rvS8b/F9I73Hx6kHePaPGwmD4uo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLnKQq%2Fbtq5u3rvS8b%2FF9I73Hx6kHePaPGwmD4uo1%2Fimg.png&quot; data-origin-width=&quot;1876&quot; data-origin-height=&quot;1362&quot; data-filename=&quot;스크린샷 2021-05-23 오후 10.48.35.png&quot; width=&quot;773&quot; height=&quot;561&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;nav_garden.xml 생성 절차 1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1650&quot; data-origin-height=&quot;956&quot; data-filename=&quot;스크린샷 2021-05-23 오후 10.50.48.png&quot; width=&quot;791&quot; height=&quot;458&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dKrOfG/btq5vd9piFS/92ZgKeGNYwVEEPaBhO8c6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dKrOfG/btq5vd9piFS/92ZgKeGNYwVEEPaBhO8c6k/img.png&quot; data-alt=&quot;nav_garden 생성 절차 2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dKrOfG/btq5vd9piFS/92ZgKeGNYwVEEPaBhO8c6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdKrOfG%2Fbtq5vd9piFS%2F92ZgKeGNYwVEEPaBhO8c6k%2Fimg.png&quot; data-origin-width=&quot;1650&quot; data-origin-height=&quot;956&quot; data-filename=&quot;스크린샷 2021-05-23 오후 10.50.48.png&quot; width=&quot;791&quot; height=&quot;458&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;nav_garden 생성 절차 2&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1621778927448&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;navigation xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;
    android:id=&quot;@+id/nav_garden&quot;
    app:startDestination=&quot;@id/view_pager_fragment&quot;&amp;gt;

    &amp;lt;fragment
        android:id=&quot;@+id/view_pager_fragment&quot;
        android:name=&quot;com.example.sunflowerexample.HomeViewPagerFragment&quot;
        tools:layout=&quot;@layout/fragment_view_pager&quot;&amp;gt;

        &amp;lt;action
            android:id=&quot;@+id/action_view_pager_fragment_to_plant_detail_fragment&quot;
            app:destination=&quot;@+id/plant_detail_fragment&quot; /&amp;gt;
    &amp;lt;/fragment&amp;gt;


    &amp;lt;fragment
        android:id=&quot;@+id/plant_detail_fragment&quot;
        android:name=&quot;com.example.sunflowerexample.PlantDetailFragment&quot;
        android:label=&quot;@string/plant_details_title&quot;
        tools:layout=&quot;@layout/fragment_gallery&quot;&amp;gt;

        &amp;lt;action
            android:id=&quot;@+id/action_plant_detail_fragment_to_gallery_fragment&quot;
            app:destination=&quot;@+id/gallery_fragment&quot; /&amp;gt;

        &amp;lt;argument
            android:name=&quot;plantId&quot;
            app:argType=&quot;string&quot; /&amp;gt;
    &amp;lt;/fragment&amp;gt;

    &amp;lt;fragment
        android:id=&quot;@+id/gallery_fragment&quot;
        android:name=&quot;com.example.sunflowerexample.GalleryFragment&quot;
        android:label=&quot;@string/plant_details_title&quot;
        tools:layout=&quot;@layout/fragment_gallery&quot;&amp;gt;

        &amp;lt;argument
            android:name=&quot;plantName&quot;
            app:argType=&quot;string&quot; /&amp;gt;
    &amp;lt;/fragment&amp;gt;

&amp;lt;/navigation&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;1256&quot; data-filename=&quot;2021-05-23 23.43.30.gif&quot; width=&quot;244&quot; height=&quot;531&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MwRRa/btq5yacPmyJ/KNVNSlFb7YtKIvQBFyxnK0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MwRRa/btq5yacPmyJ/KNVNSlFb7YtKIvQBFyxnK0/img.gif&quot; data-alt=&quot;실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MwRRa/btq5yacPmyJ/KNVNSlFb7YtKIvQBFyxnK0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/MwRRa/btq5yacPmyJ/KNVNSlFb7YtKIvQBFyxnK0/img.gif&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;1256&quot; data-filename=&quot;2021-05-23 23.43.30.gif&quot; width=&quot;244&quot; height=&quot;531&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프레그먼트가 바뀌는데 밋밋하다?&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;애니메이션 추가 ㄱㄱ&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1556&quot; data-origin-height=&quot;1252&quot; data-filename=&quot;스크린샷 2021-05-24 오전 12.05.25.png&quot; width=&quot;689&quot; height=&quot;555&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pCqao/btq5ufMNszM/Osi1y2pqGkNm9dRQhtyLVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pCqao/btq5ufMNszM/Osi1y2pqGkNm9dRQhtyLVk/img.png&quot; data-alt=&quot;애니메이션 생성 절차 1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pCqao/btq5ufMNszM/Osi1y2pqGkNm9dRQhtyLVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpCqao%2Fbtq5ufMNszM%2FOsi1y2pqGkNm9dRQhtyLVk%2Fimg.png&quot; data-origin-width=&quot;1556&quot; data-origin-height=&quot;1252&quot; data-filename=&quot;스크린샷 2021-05-24 오전 12.05.25.png&quot; width=&quot;689&quot; height=&quot;555&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;애니메이션 생성 절차 1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1654&quot; data-origin-height=&quot;954&quot; data-filename=&quot;스크린샷 2021-05-24 오전 12.06.05.png&quot; width=&quot;709&quot; height=&quot;409&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CKy6b/btq5tqg1ImD/SKKnTs9PCZckKoae2KcVQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CKy6b/btq5tqg1ImD/SKKnTs9PCZckKoae2KcVQk/img.png&quot; data-alt=&quot;애니메이션 생성 절차 2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CKy6b/btq5tqg1ImD/SKKnTs9PCZckKoae2KcVQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCKy6b%2Fbtq5tqg1ImD%2FSKKnTs9PCZckKoae2KcVQk%2Fimg.png&quot; data-origin-width=&quot;1654&quot; data-origin-height=&quot;954&quot; data-filename=&quot;스크린샷 2021-05-24 오전 12.06.05.png&quot; width=&quot;709&quot; height=&quot;409&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;애니메이션 생성 절차 2&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;anim.xml (/res/values)&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1621783188810&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;resources&amp;gt;
    &amp;lt;integer name=&quot;slide&quot;&amp;gt;200&amp;lt;/integer&amp;gt;
&amp;lt;/resources&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;slide_in_left.xml&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1621782416980&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;set xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&amp;gt;
    &amp;lt;translate android:fromXDelta=&quot;-100%&quot; android:toXDelta=&quot;0%&quot;
        android:fromYDelta=&quot;0%&quot; android:toYDelta=&quot;0%&quot;
        android:duration=&quot;@integer/slide&quot; /&amp;gt;
&amp;lt;/set&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;slide_out_left.xml&lt;/p&gt;
&lt;pre id=&quot;code_1621783096823&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;set xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&amp;gt;
    &amp;lt;translate android:fromXDelta=&quot;0%&quot; android:toXDelta=&quot;-100%&quot;
        android:fromYDelta=&quot;0%&quot; android:toYDelta=&quot;0%&quot;
        android:duration=&quot;@integer/slide&quot; /&amp;gt;
&amp;lt;/set&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;slide_in_right.xml&lt;/p&gt;
&lt;pre id=&quot;code_1621783109477&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;set xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&amp;gt;
    &amp;lt;translate android:fromXDelta=&quot;100%&quot; android:toXDelta=&quot;0%&quot;
        android:fromYDelta=&quot;0%&quot; android:toYDelta=&quot;0%&quot;
        android:duration=&quot;@integer/slide&quot; /&amp;gt;
&amp;lt;/set&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;slide_in_right.xml&lt;/p&gt;
&lt;pre id=&quot;code_1621783126619&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;set xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;&amp;gt;
    &amp;lt;translate android:fromXDelta=&quot;100%&quot; android:toXDelta=&quot;0%&quot;
        android:fromYDelta=&quot;0%&quot; android:toYDelta=&quot;0%&quot;
        android:duration=&quot;@integer/slide&quot; /&amp;gt;
&amp;lt;/set&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;duration&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 실행 시간&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;fromXDelta&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 시작 X축 값 (0% = 처음 자리)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;toXDelta&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 끝 X축 값 (100% = 오른쪽으로 100%만큼 이동) (-100% = 왼쪽으로 100%만큼 이동)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;fromYDelta&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 시작 Y축 값 (0% = 처음 자리)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;toYDelta&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 끝 Y축 값 (200% = 아래쪽으로 200%만큼 이동) (-200% = 위쪽으로 200%만큼 이동)&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;nav_garden.xml&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1621783228381&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;navigation xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;
    android:id=&quot;@+id/nav_garden&quot;
    app:startDestination=&quot;@id/view_pager_fragment&quot;&amp;gt;

    &amp;lt;fragment
        android:id=&quot;@+id/view_pager_fragment&quot;
        android:name=&quot;com.example.sunflowerexample.HomeViewPagerFragment&quot;
        tools:layout=&quot;@layout/fragment_view_pager&quot;&amp;gt;

        &amp;lt;action
            android:id=&quot;@+id/action_view_pager_fragment_to_plant_detail_fragment&quot;
            app:destination=&quot;@+id/plant_detail_fragment&quot;
            app:exitAnim=&quot;@anim/slide_out_left&quot;
            app:enterAnim=&quot;@anim/slide_in_right&quot;
            app:popEnterAnim=&quot;@anim/slide_in_left&quot;
            app:popExitAnim=&quot;@anim/slide_out_right&quot; /&amp;gt;
    &amp;lt;/fragment&amp;gt;


    &amp;lt;fragment
        android:id=&quot;@+id/plant_detail_fragment&quot;
        android:name=&quot;com.example.sunflowerexample.PlantDetailFragment&quot;
        android:label=&quot;@string/plant_details_title&quot;
        tools:layout=&quot;@layout/fragment_gallery&quot;&amp;gt;

        &amp;lt;action
            android:id=&quot;@+id/action_plant_detail_fragment_to_gallery_fragment&quot;
            app:destination=&quot;@+id/gallery_fragment&quot;
            app:enterAnim=&quot;@anim/slide_in_right&quot;
            app:exitAnim=&quot;@anim/slide_out_left&quot;
            app:popEnterAnim=&quot;@anim/slide_in_left&quot;
            app:popExitAnim=&quot;@anim/slide_out_right&quot; /&amp;gt;

        &amp;lt;argument
            android:name=&quot;plantId&quot;
            app:argType=&quot;string&quot; /&amp;gt;
    &amp;lt;/fragment&amp;gt;

    &amp;lt;fragment
        android:id=&quot;@+id/gallery_fragment&quot;
        android:name=&quot;com.example.sunflowerexample.GalleryFragment&quot;
        android:label=&quot;@string/plant_details_title&quot;
        tools:layout=&quot;@layout/fragment_gallery&quot;&amp;gt;

        &amp;lt;argument
            android:name=&quot;plantName&quot;
            app:argType=&quot;string&quot; /&amp;gt;
    &amp;lt;/fragment&amp;gt;

&amp;lt;/navigation&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;app:enterAnim&lt;/b&gt; : A -&amp;gt; B로 Action할 때 들어오는 UI 대상의 Animation(B의 Animation)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;app:exitAnim&lt;/b&gt; : A -&amp;gt; B로 Action할 때 나가는 UI 대상의 Animation(A의 Animation)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;app:popEnterAnim&lt;/b&gt; : B -&amp;gt; A로 Pop할 때 들어오는 UI 대상의 Animation(A의 Animation)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;app:popExitAnim&lt;/b&gt; : B -&amp;gt; A로 Pop할 때 나가는 UI 대상의 Animation(B의 Animation)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;1238&quot; data-filename=&quot;2021-05-24 00.21.00.gif&quot; width=&quot;260&quot; height=&quot;559&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k9l6x/btq5DDZo9S7/91xDnrchugDUDmKouHrf1k/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k9l6x/btq5DDZo9S7/91xDnrchugDUDmKouHrf1k/img.gif&quot; data-alt=&quot;실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k9l6x/btq5DDZo9S7/91xDnrchugDUDmKouHrf1k/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/k9l6x/btq5DDZo9S7/91xDnrchugDUDmKouHrf1k/img.gif&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;1238&quot; data-filename=&quot;2021-05-24 00.21.00.gif&quot; width=&quot;260&quot; height=&quot;559&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/android/sunflower&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/android/sunflower&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1621781401191&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;android/sunflower&quot; data-og-description=&quot;A gardening app illustrating Android development best practices with Android Jetpack. - android/sunflower&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/android/sunflower&quot; data-og-url=&quot;https://github.com/android/sunflower&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bqINX1/hyKjNnbSQc/0UAKHAu3tTA29hni6pyp3K/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bZ45Dz/hyKibQNaIm/KKVHjf1PoWyZFmFdkkytOK/img.png?width=1600&amp;amp;height=808&amp;amp;face=0_0_1600_808,https://scrap.kakaocdn.net/dn/fE3li/hyKilZ95Kw/mhu7nRbUwnZdOSADAXkKAk/img.png?width=240&amp;amp;height=501&amp;amp;face=0_0_240_501&quot;&gt;&lt;a href=&quot;https://github.com/android/sunflower&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/android/sunflower&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bqINX1/hyKjNnbSQc/0UAKHAu3tTA29hni6pyp3K/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bZ45Dz/hyKibQNaIm/KKVHjf1PoWyZFmFdkkytOK/img.png?width=1600&amp;amp;height=808&amp;amp;face=0_0_1600_808,https://scrap.kakaocdn.net/dn/fE3li/hyKilZ95Kw/mhu7nRbUwnZdOSADAXkKAk/img.png?width=240&amp;amp;height=501&amp;amp;face=0_0_240_501');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;android/sunflower&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A gardening app illustrating Android development best practices with Android Jetpack. - android/sunflower&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android/Kotlin</category>
      <category>Android</category>
      <category>Kotlin</category>
      <category>Navigation</category>
      <category>안드로이드</category>
      <category>코틀린</category>
      <author>혀가 길지 않은 개발자</author>
      <guid isPermaLink="true">https://jwsoft91.tistory.com/271</guid>
      <comments>https://jwsoft91.tistory.com/271#entry271comment</comments>
      <pubDate>Sun, 23 May 2021 23:09:29 +0900</pubDate>
    </item>
  </channel>
</rss>