<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>dev316316316.log</title>
        <link>https://velog.io/</link>
        <description>백엔드 개발자로 변신.</description>
        <lastBuildDate>Sun, 22 Oct 2023 06:10:50 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>dev316316316.log</title>
            <url>https://velog.velcdn.com/images/hui__ii/profile/6d02cf2b-7083-4775-918f-b3dd8bacf217/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. dev316316316.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/hui__ii" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[콜백 / 싱글톤 패턴]]></title>
            <link>https://velog.io/@hui__ii/%EC%BD%9C%EB%B0%B1-%EC%8B%B1%EA%B8%80%ED%86%A4-%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@hui__ii/%EC%BD%9C%EB%B0%B1-%EC%8B%B1%EA%B8%80%ED%86%A4-%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Sun, 22 Oct 2023 06:10:50 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/hui__ii/post/ce274d86-491a-47d0-b07e-8c0926afb3de/image.png" alt=""></p>
<h1 id="콜백이란">콜백이란?</h1>
<p>call back:  어떤 함수의 파라미터로 들어오는 함수.</p>
<p>비동기 처리 패턴은 기본 스레드를 차단하지 않고 장기 실행 작업을 수행하기 위한 방식이다. 이 패턴에서, 작업을 백그라운드 스레드에서 시작하고, 작업이 완료되면 기본 스레드에 결과를 알리는 콜백을 호출. 후에 이벤트에 대한 처리가 가능하다.</p>
<p>ex) 클릭리스너 : 클릭을 감지하면 onCLickListener를 호출하여 이벤트 처리. 외에 에러처리, 데이터 로딩, 쓰레드 작업 등 여러 사용.</p>
<p>→ 비동기로 실행되기 때문에 많이 사용하면 코드를 읽기 힘들며 추론 힘듬. </p>
<h1 id="싱글톤-패턴이란">싱글톤 패턴이란?</h1>
<p>singleton pattern: 객체의 인스턴스를 한개만 생성되게 하는 패턴.</p>
<p>싱글턴 패턴이란 반복적으로 일어나는 문제들을 어떻게 풀어나갈 수 있는지 방법을 만들어 둔 디자인 패턴 중 하나이다.  </p>
<h3 id="왜-사용하는-걸까">왜 사용하는 걸까?</h3>
<ul>
<li>인스턴스를 많이 만들면 <strong>불필요한 자원 메모리</strong>가 많아진다.</li>
<li>이미 생성된 인스턴스를 활용하며 속도 측면에서 좋다.</li>
<li>전역으로 사용되는 인스턴스이므로 다른 여러 클래스에서 데이터를 공유하며 사용.</li>
</ul>
<p>→ 다른 클래스의 인스턴스들 간에 결합도가 높아져 객체 지향 설계에 어긋나며 수정이 어려워지고, 멀티쓰레드 환경에서 동기화 처리를 안하면 인스턴스가 2개 생성될 수도 있는등 문제가 발생.</p>
<p>→ 다른 클래스의 인스턴스들 간에 결합도가 높아져 객체 지향 설계에 어긋나며 수정이 어려워지고, 멀티쓰레드 환경에서 동기화 처리를 안하면 인스턴스가 2개 생성될 수도 있는등 문제가 발생.</p>
<h3 id="싱글톤-구현해보자">싱글톤, 구현해보자!</h3>
<pre><code class="language-kotlin">class DBHandler private constructor(context: Context) {
    companion object {
        private var instance: DBHandler? = null

        fun getInstance(context: Context) =
            instance ?: DBHandler(context).also {
                instance = it
            }
    }
}</code></pre>
<p>private를 이용해 외부에서 생성자에 접근하지 못하게 막고, getInstance를 통해야만 인스턴스를 만들 수 있게 함. 후에 instance를 확인해 값이 없으면 새로 만드록, </p>
<p>그렇지 않으면 기존값을 반환하는 구조이다. 이 때 생성자는 context를 전달받을 수 있게 구성하였다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[백준] 1934번: 최소공배수]]></title>
            <link>https://velog.io/@hui__ii/%EB%B0%B1%EC%A4%80-1934%EB%B2%88-%EC%B5%9C%EC%86%8C%EA%B3%B5%EB%B0%B0%EC%88%98</link>
            <guid>https://velog.io/@hui__ii/%EB%B0%B1%EC%A4%80-1934%EB%B2%88-%EC%B5%9C%EC%86%8C%EA%B3%B5%EB%B0%B0%EC%88%98</guid>
            <pubDate>Sat, 09 Sep 2023 15:03:40 GMT</pubDate>
            <description><![CDATA[<h1 id="code">code</h1>
<pre><code>import sys

def getnum(a, b):
    x = max(a, b)
    y = min(a, b)
    while True:
        temp = x % y
        if temp == 0:
            result = y
            break
        x = y
        y = temp
    return result * (a//result) * (b//result)

t = int(sys.stdin.readline())

for i in range(t):
    a, b = map(int, input().split())
    print(getnum(a, b))</code></pre><p>끄적끄적,,</p>
<p><img src="https://velog.velcdn.com/images/hui__ii/post/16e85c57-db60-41c2-aa0d-901cbfb47650/image.jpeg" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자료구조] 큐]]></title>
            <link>https://velog.io/@hui__ii/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%ED%81%90</link>
            <guid>https://velog.io/@hui__ii/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%ED%81%90</guid>
            <pubDate>Tue, 29 Aug 2023 03:41:11 GMT</pubDate>
            <description><![CDATA[<h1 id="👉-큐">👉 큐?</h1>
<p>FIFO (선입선출) : 가장 먼저 들어온 것이 가장 먼저 나가는 구조</p>
<p>큐의 맨 앞의 원소 (맨 먼저 큐에 들어온 원소) : front
맨 뒤에 있는 원소 (맨 나중에 큐에 들어온 원소) : tail</p>
<h3 id="특징">특징</h3>
<p>삽입할 때는 삽입할 원소를 알려주어야 하지만, 삭제할 때는 단순히 삭제!
⇒ 삭제원소는 명시필요x 무조건 맨 앞에 있는 것을 삭제하기 때문.</p>
<p><strong>원소는 큐에서 맨 뒤에 삽입, 맨 앞의 원소를 삭제.</strong>
<img src="https://velog.velcdn.com/images/hui__ii/post/133723ee-1ddf-4966-92b7-a0163a3e90b0/image.png" alt=""></p>
<h3 id="원리">원리</h3>
<p>큐에 새 원소를 삽입할 때는 항상 큐의 맨 끝에 삽입, 삭제할 때는 무조건 프론트의 원소 삭제.</p>
<blockquote>
<p>1) enqueue(x) : 큐 끝에 원소 x 삽입
2) dequeue(): 큐 맨 앞에 있는 원소를 알려주고 삭제.
3) front() : 큐 맨 앞에 있는 원소를 알려준다
4) isEmpty(): 큐가 비어 있는지 알려준다.
5) dequeueAll(): 큐를 깨끗이 청소한다.</p>
</blockquote>
<hr>
<p>배운거 더 추가해서 작성예정.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자료구조] 스택]]></title>
            <link>https://velog.io/@hui__ii/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%8A%A4%ED%83%9D</link>
            <guid>https://velog.io/@hui__ii/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%8A%A4%ED%83%9D</guid>
            <pubDate>Mon, 28 Aug 2023 23:18:10 GMT</pubDate>
            <description><![CDATA[<h1 id="👉-스택">👉 스택?</h1>
<p>LIFO (후입선출) : 뒤에 들어온 것이 가장 먼저 나가는 구조.</p>
<p>키보드 입력을 하다 백스페이스를 누르면 최근에 입력한 글자를 지운다거나, 편집기에서 최근에 한 작업순으로 취소를 하는 기능 정도를 스택이 사용되는 예시로 들 수 있겠다.</p>
<h3 id="특징">특징</h3>
<p><strong>맨 위의 원소만 접근 가능.</strong></p>
<p><img src="https://velog.velcdn.com/images/hui__ii/post/e8dd3577-2d4c-476a-aac7-665fd59ceab4/image.jpeg" alt=""></p>
<p>스택의 <strong>맨 위 원소(스택탑) 위에 원소를 삽입</strong> 해 새 스택탑이 되게 하고, 
삭제의 경우에는 <strong>무조건 탑에 있는 원소를 삭제</strong> 하고 그 밑 원소가 스택탑이 된다.</p>
<p>ex) 스택의 맨 위에는 현재 수행 중인 함수의 정보가 저장되고, 이 함수를 호출한 함수는 바로 아랫 공간에 저장되어있다. 그래서 수행을 마친 함수가 스택 영역에서 지워지면 호출한 함수의 정보가 스택의 맨 위에 있게 된다. -&gt; <em>프로그램이 수행되는 경로를 효율적으로 따라갈 수o</em></p>
<h3 id="원리">원리</h3>
<p>삽입 할 때는 삽입할 원소를 명시하지만, 삭제 할 때는 단순히 맨 위의 원소를 삭제한다. 스택에서 내용을 알려달라하면 무조건 맨 위에 있는 것을 알려줌.</p>
<blockquote>
<p>1) isEmpty : 공백상태(비어있는 상태)인가?
2) isFull: 포화상태(가득 차 있는 상태)인가?<br>
스택의 두 가지 오류사항 : </p>
</blockquote>
<ul>
<li>오버플로우: 리스트가 꽉 차 요소를 삽입할 수 없는 경우.</li>
<li>언더플로: 리스트 안에 요소가 없어 삭제나 참조 불가.<br>
3) push(e) : 요소 e를 스택의 맨 위에 추가. 삽입 전 초화상태인지 아닌지를 먼저 검사.
4) pop() : 스택의 맨 위에 있는 요소를 꺼내 반환. 반환 전 공백상태인지 아닌지를 먼저 검사. </li>
</ul>
<p>스택은 <strong>동적인 메모리 구조</strong> 로 함수 호출과 관련된 정보를 관리한다.</p>
<p><img src="https://velog.velcdn.com/images/hui__ii/post/81b8a0c2-1c89-4a76-aa0a-08b55407f5a4/image.png" alt=""></p>
<ul>
<li>*<em>정적 영역 (static) *</em> : 컴파일 직후 상대적인 위치를 정할 수 있는 모든 정보가 있음.</li>
<li><strong>동적 영역 (dynamic)</strong> : 수행을 시작한 후에야 알 수 있음. 정적 영역에는 프로그램 수행 코트와 프로그램이 끝날 때까지 존재하는 데이터(정적, 전역 변수)가 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자료구조] 알고리즘 성능]]></title>
            <link>https://velog.io/@hui__ii/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%84%B1%EB%8A%A5</link>
            <guid>https://velog.io/@hui__ii/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%84%B1%EB%8A%A5</guid>
            <pubDate>Mon, 28 Aug 2023 15:15:34 GMT</pubDate>
            <description><![CDATA[<h1 id="👉-알고리즘-수행-시간이란">👉 알고리즘 수행 시간이란</h1>
<ul>
<li>알고리즘 효율성 : <strong>자원(시간)</strong> 을 얼마나 효율적으로 사용하는가. 대부분 <strong>수행시간</strong> 과 관련!<br>

</li>
</ul>
<p>변수에 값을 할당하거나 리턴, 반복문을 돌릴 때, 함수를 호출할 때 모두 수행시간에 관여한다.</p>
<h1 id="👉-알고리즘-복잡도">👉 알고리즘 복잡도</h1>
<p>알고리즘의 복잡도를 나타낼 때는 <code>점근적 표기</code>를 쓴다. </p>
<ul>
<li><strong>점근적 표기</strong>: 입력이 충분히 클 때의 복잡도 (입력이 작으면 복잡하든 효율적이든 수행시간 차이가 별로 안 남)</li>
</ul>
<br>
표기의 예를 들면.. 2n+3 이지만 점근적 복잡도에서는 n 이라 표기!

<p> <strong>최고차항의 차수만 중요</strong>, 나머지는 다 무시한다. (상수를 곱하든 않든 차수에 비하면 미미하기 때문)</p>
<p>n, nlogn, n², 2n 등이 있다.</p>
<hr>
<h2 id="👉-점근적-복잡도-대표적-3가지">👉 점근적 복잡도 대표적 3가지</h2>
<h3 id="0-빅오-표기">0 (빅오) 표기</h3>
<ul>
<li>0(n²) : 최고차항의 차수가 <strong>n²을 넘지 않는</strong> 모든 함수의 집합</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hui__ii/post/cc134a91-dfa7-4263-bf19-b8d38b40a197/image.png" alt=""></p>
<blockquote>
<p>상한으로 <strong>최악의 경우의 시간 복잡도</strong> 를 나타낸다.</p>
</blockquote>
<p> 여기서 n²은 2차 함수를 총칭하므로 n², 3n³+2n, 5n²-7nlogn 등의 2차 함수가 다 포함되며, 2차 미만의 함수도 포함된다. </p>
<p> 위 예시들을 전부** 0(n²)** 으로 표현해도 되지만 정보손실이 생긴다. 0(2¹⁰⁰) 이라 표현해도 되지만 정보 가치가 전혀 없는 표현이 되기 때문에 엄밀하게 한도를 파악하는 것이 중요하다. <strong>정보 손실이 덜한 쪽으로 표현하자.</strong></p>
<p>추가로, 정렬 알고리즘 중 하나인 버블 정렬(Bubble Sort)의 시간 복잡도가 O(n²)인 경우, n개의 원소를 정렬할 때 최악의 경우에는 비교 및 교환 연산이 n² 번 수행됩다고 이해하면 된다. </p>
<br>

<h3 id="ω-오메가-표기">Ω (오메가) 표기</h3>
<ul>
<li>Ω(n²): 최고차항의 차수가 <strong>n²보다 작지 않은</strong> 모든 함수의 집합을 뜻함. </li>
</ul>
<blockquote>
</blockquote>
<p>하한으로 <strong>최선의 경우의 시간 복잡도</strong> 를 나타낸다.</p>
<p>이 알고리즘의 점근적 표기가 Ω(n²) 라면, 적어도 실행시간이 n²에 비례하는 시간이 걸린다는 거다.</p>
<p>알고리즘의 실행 시간이 최선의 경우에 얼마나 적게 증가하는지를 나타냄. 예를 들어, 비교 기반 정렬 알고리즘은 최선의 경우에도 모든 원소를 비교해야 하므로, 어떤 최선의 경우에도 최소한 O(n*log(n))의 시간이 걸린다. (머지 소트, 퀵 소트 등이 가지는 시간 복잡도)</p>
<br>

<h3 id="θ-세타-표기">Θ (세타) 표기</h3>
<ul>
<li>Θ (n²): 최고차항의 차수가 <strong>정확히 n²인</strong> 모든 함수의 집합.</li>
</ul>
<p>Θ 표기에는 상한과 하한이 다 포함되어 있다.</p>
<p> 0(n³), Ω(n³) 이기도 하면, 상한과 하한이 겹치므로 Θ(n³)이기도 하다! 이런 경우에는 n³의 형태로 증가한다는 것을 알 수 있기 때문에 더 정확하게 시간복잡도의 정보를 얻을 수 있다!</p>
<p> 그래도.. 상한과 하한이 겹치지 않거나 하나를 파악하기가 힘들다면 빅오나 오메가 표기를 쓰도록 하자.</p>
<hr>
<h1 id="👉-마무리">👉 마무리</h1>
<p>0 (빅오) : 점근적 상한 -&gt; 최악의 성능 
Ω (오메가) : 점근적 하한 -&gt; 최선의 성능
Θ (세타) : 점근적 동일 -&gt; 평균의 성능
<br>
&#39;쉽게 배우는 자료구조 with파이썬&#39; 와 인터넷 자료를 참고합니다! 간단한 정리이기 때문에.. 자세하지는 않다는점 참고해주세요. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[소마고 연합 토크 콘서트 2023]]></title>
            <link>https://velog.io/@hui__ii/%EC%86%8C%EB%A7%88%EA%B3%A0-%EC%97%B0%ED%95%A9-%ED%86%A0%ED%81%AC-%EC%BD%98%EC%84%9C%ED%8A%B8-2023</link>
            <guid>https://velog.io/@hui__ii/%EC%86%8C%EB%A7%88%EA%B3%A0-%EC%97%B0%ED%95%A9-%ED%86%A0%ED%81%AC-%EC%BD%98%EC%84%9C%ED%8A%B8-2023</guid>
            <pubDate>Mon, 28 Aug 2023 02:55:37 GMT</pubDate>
            <description><![CDATA[<h2 id="🤤">🤤</h2>
<p>기다리 고기다리 던.. 소마고 연합 토크 콘서트에 갔다왔습니다! 올해 대소마고에 처음 들어온 저에게는 처음엔 뭔 행사인가 싶었지만.. 소프트웨어 마이스터고 학생들이 한 자리에 다 모인다는 소식을 듣고선 정말 소마고들은 재밌는 행사를 만드는구나 싶었습니다...멋짐</p>
<p><img src="https://velog.velcdn.com/images/hui__ii/post/e8118544-ea21-4c77-84a6-3d5258d56a56/image.png" alt="">
23. 8. 24 | 부산 라도무스 아트센터. 텐션 높은 사회자 분과 함께 시작하였다.</p>
<p><del>노래 틀고 장기자랑 같은거 했는데 대부분 부마고라서 IT 말고 다른것도 배우구나 생각함!</del></p>
<p><code>명함교환</code> 이라는 소마고 연합 콘서트의 빠질 수 없는 이 요소는.. 가장 재밌었던 부분. 대소고에서는 이걸 위해서 여름방학 전에 폼을 돌려서 명함 만들기를 예고했었는데, 다른 학교도 비슷한지 각자 학교 명함, 동아리 명함 등등 개성있게 가져왔더라고요.</p>
<p><img src="https://velog.velcdn.com/images/hui__ii/post/0946064d-ed68-4a82-a292-51356da2421f/image.png" alt=""></p>
<p>저같은 경우엔 우물쭈물 서 있다가 눈 딱 맞으면 명함 교환하는 느낌이였는데 다들 밝게 인사하며 명함 건네주셔서 기분이 좋았습니다.. 저희 학교, 타학교 모두 반가웠어요.</p>
<p>사실 명함에 넣을 문구를 3일동안 고민했답니다 🤤 똑같은 양식의 명함에서 별거 아닐지도 모르지만 신박한걸 넣고싶어서! </p>
<h2 id="👉-전문가-전공-강의">👉 전문가 전공 강의</h2>
<p>  <code>인사채용</code> <code>UI UX</code> <code>SW 창업</code> <code>프론트 엔드</code> <code>백엔드</code> <code>어플리케이션 개발</code></p>
<p>분야가 있었는데 저는 안드로이드 개발을 하지만 서버 쪽을 알아야 앱개발도 더 잘할 수 있다고 생각해서 백엔드, 창업 강의를 들었어요. </p>
<h3 id="백엔드--문범우-개발자">백엔드 : 문범우 개발자</h3>
<p>생각했던 전공에 관한 기술의 강의는 아니였고, 개발자가 되서 맞이했던 힘든 점을 어떻게 극복할 것인가. 가 주요 내용이었다. 개발자라는 역할으로써 개발기술을 잘 다루는것도 중요하지만, <strong>다양한 경험을 함</strong> 으로써 <strong>새로운 아이디어</strong> 를 내는 것 또한 매우 중요하다고 한다! </p>
<p><del>스카이다이빙.. 인가 익사이팅 운동을 하시는걸 좋아하신다고.</del></p>
<h3 id="sw-창업--최지연-대표">SW 창업 : 최지연 대표</h3>
<p>온택트 콘택트 코리아라는 스타트업을 실제로 하신 최지연 대표님의 이야기를 중심으로, 창업 성공을 위해서는 어떤 노력을 할 수 있는지 알 수 있는 강의였다.</p>
<blockquote>
<p>의사소통, 대인관계, 자신감, 도전정신, 진취성, 위험감수성과 같은 <strong>기업가 정신</strong> 을 가져보자! 창업한지 3년이라는 고비를 넘기면 점점 더 성장하는 내 회사를 보게 될지도!</p>
</blockquote>
<p>타인이 한 말에 긍정적인 부분을 말하는 예의와 자신의 열정을 그들에게 보여주자. 상품을 판매할 때는 스토리를 만들고, 성과지표를 만들어 결과에 대한 의논과 앞길을 내다보는 것이 좋다고 한다.
<img src="https://velog.velcdn.com/images/hui__ii/post/0172e34a-df99-4380-b20f-1a9ea489dff5/image.png" alt=""></p>
<br>

<p>두 강사분들 다 자신의 연락처를 남기며 학생들의 질문을 흔쾌히 받아 답변해주셨다. 소프트웨어 학생들, 꿈을 가지는 학생들에게 도움이 되고자 하는 모습이 보여주셔 감사한! 😇
<br></p>
<h2 id="👉-마무--리">👉 마무 ~ 리</h2>
<p><img src="https://velog.velcdn.com/images/hui__ii/post/26dc4498-4cde-49c0-ae68-dda8ca58c037/image.png" alt=""></p>
<p>어느쪽에서 선물을 준건지는 잘 모르지만,  <code>카드지갑</code> <code>과자박스</code> 를 학교로 돌아가는 중에 받았다! 학교에서 마트가기 귀찮았는데.. 식량이 생겨서 기쁩니다. </p>
<p>이렇게 많은 학생들이 IT 분야로 뛰어든다고 생각하니 동질감 때문인지 엄마마음으로 응원하고 있었음. 다들 열심히 공부하시고 꼬옥 바라는 목표를 이루시길 바랍니다. 화이팅! </p>
<p>이 행사로 다른 학교랑 교류할 수 있는 통로를 만들 수 있어 좋았어요.
밥도 맛있었고 내 미래를 한번 더 생각하게 만든 유익했던 행사! 내년에는 어느 지역으로 갈지 기대되네요. 🤤🤤</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Android Studio] 네비게이션]]></title>
            <link>https://velog.io/@hui__ii/Android-Studio-%EB%84%A4%EB%B9%84%EA%B2%8C%EC%9D%B4%EC%85%98</link>
            <guid>https://velog.io/@hui__ii/Android-Studio-%EB%84%A4%EB%B9%84%EA%B2%8C%EC%9D%B4%EC%85%98</guid>
            <pubDate>Sun, 20 Aug 2023 04:44:06 GMT</pubDate>
            <description><![CDATA[<h1 id="navigation">Navigation..</h1>
<p>Navigation Component는 Fragment에서 화면간의 이동을 쉽게 구현하도록 도와주는 역할을 한다. Fragment간의 플로우를 시각적으로 볼수 있다는 특징이 있어 앱 플로우를 보거나 할때 유용하게 쓸 수 있다.</p>
<h3 id="구성요소">구성요소</h3>
<ul>
<li><p>*<em>Navigation Graph *</em>: 모든 네비게이션 관련 정보가 모여있는 XML 리소스. 사용자가 앱에서 갈 수 있는 모든 플로우를 보여주고 앱내의 프래그먼트를 한눈에 확인할 수 있다.</p>
</li>
<li><p><strong>NavHostFragment</strong> : 네비게이션 그래프에 정의된 각 화면의 컨테이너 역할을 하는 프래그먼트. 액티비티나 프래그먼트 내에 포함되며, 네비게이션 그래프에 따라 화면을 표시하고 관리한다. 화면전환, 뒤로가기 동작을 처리하여 사용자의 탐색을 관리.</p>
</li>
<li><p><strong>NavController</strong> : 사용자가 앱 내에서 이동할 때 NavHost에서 대상 콘텐츠를 정해주는 역할을 한다. </p>
<br>
##### 간단히 말하자면..
Navigation Graph의 경로를 따라 이동하거나 특정 화면으로 직접 이동하고자 할 때, 이 정보를 NavController에게 전달하여 NavController가 알맞은 화면을 NavHost에서 표시하도록 함.

</li>
</ul>
<h3 id="사용장점-">사용장점 :</h3>
<ul>
<li>화면전환에 대한 표준화된 애니메이션 리소스</li>
<li>프래그먼트의 트랜잭션 처리로 간단한 화면전환</li>
<li>Safe Args 플러그인을 사용하여 데이터를 대상 사이에서 안전하게 전달</li>
</ul>
<hr>
<h1 id="👉-navigation-사용하기">👉 Navigation 사용하기</h1>
<h3 id="1-권한-설정">1) 권한 설정</h3>
<pre><code>dependencies {
    implementation &quot;androidx.navigation:navigation-fragment:$nav_version&quot;
    implementation &quot;androidx.navigation:navigation-ui:$nav_version&quot;
}

</code></pre><h3 id="2-네비게이션-그래프-설정">2) 네비게이션 그래프 설정</h3>
<p>네비게이션 package를 생성 후, nav_grph xml 리소스를 만들어 프래그먼트를 추가해준다. 후에 코드에서 action을 지정하거나 디자인칸에서 선을 이어 경로를 정해준다.</p>
<p><strong>startDestination</strong> 속성을 이용해 시작 프래그먼트를 지정해주거나 디자인탭에서 프래그먼트를 클릭하고 집모양 버튼을 눌러주면 <strong>시작 프래그먼트를 설정</strong>할 수 있다.
<img src="https://velog.velcdn.com/images/hui__ii/post/7ffe774d-51b1-40b7-8a4d-2fefcd329a6b/image.png" alt=""></p>
<pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&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_graph&quot;
            app:startDestination=&quot;@id/FirstFragment&quot;&gt;

    &lt;fragment
            android:id=&quot;@+id/FirstFragment&quot;
            android:name=&quot;com.student.yejin.FirstFragment&quot;
            android:label=&quot;첫번째 프레그먼트&quot;
            tools:layout=&quot;@layout/fragment_first&quot;&gt;

        &lt;action
                android:id=&quot;@+id/action_FirstFragment_to_SecondFragment&quot;
                app:destination=&quot;@id/SecondFragment&quot;/&gt;
        &lt;action android:id=&quot;@+id/action_FirstFragment_to_ThirdFragment&quot; app:destination=&quot;@id/ThirdFragment&quot;/&gt;
    &lt;/fragment&gt;
    &lt;fragment
            android:id=&quot;@+id/SecondFragment&quot;
            android:name=&quot;com.student.yejin.SecondFragment&quot;
            android:label=&quot;두번째 프레그먼트&quot;
            tools:layout=&quot;@layout/fragment_second&quot;&gt;

        &lt;action
                android:id=&quot;@+id/action_SecondFragment_to_FirstFragment&quot;
                app:destination=&quot;@id/FirstFragment&quot;/&gt;
    &lt;/fragment&gt;
    &lt;fragment
            android:id=&quot;@+id/ThirdFragment&quot;
            android:name=&quot;com.student.yejin.ThirdFragment&quot;
            android:label=&quot;세번째 프레그먼트&quot;
            tools:layout=&quot;@layout/fragment_third&quot;&gt;
        &lt;action
                android:id=&quot;@+id/action_ThirdFragment_to_SecondFragment&quot;
                app:destination=&quot;@id/FirstFragment&quot;/&gt;
    &lt;/fragment&gt;
&lt;/navigation&gt;
</code></pre><br>

<h3 id="3-navhostfragment-추가-xml">3) NavHostFragment 추가 (xml)</h3>
<pre><code>&lt;fragment
    android:id=&quot;@+id/nav_host_fragment&quot;
    android:name=&quot;androidx.navigation.fragment.NavHostFragment&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    app:navGraph=&quot;@navigation/nav_graph&quot; /&gt;

    //activity_main 에 추가
</code></pre><br>

<h3 id="4-화면-간-전환">4) 화면 간 전환</h3>
<pre><code>val navController = findNavController(R.id.nav_host_fragment)
navController.navigate(R.id.destination_id)
</code></pre><p>findNavController 안에는 xml에 만든 NavHostFragment의 아이디를 넣는다.</p>
<p>navigate 안에는 &quot;@+id/action_FirstFragment_to_ThirdFragment&quot; 와 같은 nav_graph에서 지정한 액션 아이디를 넣어주면 된다.
<br></p>
<h1 id="👉-마무리">👉 마무리</h1>
<p>화면 전환 뿐만 아니라 bundle을 사용해 값을 navigate로 보낼 수도 있다. 또한 바텀 네비게이션, 네비게이션 드로어에 사용하여 메뉴 아이템을 선택하거나 네비게이션 메뉴를 열 때 특정 화면으로 전환할 수 있다. </p>
<p>화면 전환에 대한 애니메이션 및 전환 효과 또한 쉽게 부여할 수 있으니 도전해보자..... (예진아)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Android Studio] MVP에 대하여.]]></title>
            <link>https://velog.io/@hui__ii/Android-Studio-MVP%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC</link>
            <guid>https://velog.io/@hui__ii/Android-Studio-MVP%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC</guid>
            <pubDate>Tue, 15 Aug 2023 09:03:55 GMT</pubDate>
            <description><![CDATA[<p>Android는 사실 Class 하나로 MVP의 처리가 가능한 구조로 만들 수 있지만, 코드가 1000줄과 같이 넘어간다면 가독성이 떨어지고 유지보수 하는데 힘이 든다.</p>
<p>이에 Business Logic을 Model, View, Presenter로 분리함으로써 명확한 업무 분담을 행하도록 하자!</p>
<p>이는 MVC와 다르게 UI(<strong>View</strong>)와 로직(<strong>Model</strong>)을 완전히 분리하고, 서로 간에 상호작용을 <strong>Presenter</strong>에 그 역할을 줌으로써, 서로의 영향(의존성)을 최소화한다. 
(모델은 뷰를 직접적으로 전혀 컨트롤하지 못하게 된다.)</p>
<p>더하여서 새로운 액티비티를 생성했을 때, 손쉽게 프리젠터를 그쪽으로 이식할 수 있다.</p>
<h1 id="mvp">MVP</h1>
<p>(Model-View-Presenter)
<img src="https://velog.velcdn.com/images/hui__ii/post/41b89268-b348-4ff9-9dd7-7beb5a093860/image.png" alt=""></p>
<ul>
<li><p><strong>Model</strong>
데이터와 비즈니스 로직을 담당한다. 데이터를 처리하고 저장하며, 프리젠터와 통신하여 <strong>데이터의 변경 사항을 전달</strong>하는 역할. </p>
</li>
<li><p><strong>View</strong>
사용자 인터페이스(UI)를 표시하며, 사용자의 입력을 받아 처리한다. <strong>프리젠터와 상호작용하여 필요한 데이터를 요청하고, 데이터의 변경 사항을 표시</strong>.</p>
</li>
<li><p><strong>Presenter</strong> 
뷰와 모델 사이의 중재자 역할. 뷰로부터 사용자 입력을 받아 모델에 전달하고, 모델에서 받은 <strong>데이터를 가공</strong>하여 뷰에 전달합니다. 뷰와 모델 간의 결합도를 낮춰주는 역할을 한다. </p>
</li>
</ul>
<br>


<hr>
<h1 id="👉-예제">👉 예제</h1>
<p><a href="https://youtu.be/LyYRTcyKJIU">https://youtu.be/LyYRTcyKJIU</a>
전에 한 MVC 예제를 MVP패턴으로 바꾸어 보며 어떻게 구성하는지 정리하였다.</p>
<h4 id="1-프리젠터-생성">1) 프리젠터 생성</h4>
<p>프리젠터 클래스를 생성한 후, 메인 액티비티의 <strong>뷰</strong>를 변경하는 코드와 <strong>모델</strong>을 넘겨준다.</p>
<p>뷰를 제어하고 관리할 때에는 <code>viewInterface</code> 에 접근하고
데이터를 관리할 때에는 <code>model</code> 클래스에 접근하면 된다!</p>
<p>이렇게 뷰를 관리하고 필요한 데이터를 가져오거나 넘길 때에 프리젠터를 사용한다.</p>
<pre><code>class Presenter(var viewInterface: ViewInterface){
    //파라미터로 받은 뷰 인터페이스를 현 클래스의 인터페이스에 할당.

    var model = Model() //모델과

    //뷰를 변경하는 코드를 가진다.
    fun clickNumber (i: Int) {
        viewInterface.toastMessage(i)
        model.inputPassword(i)

        if (model.password.size == 4 &amp;&amp; model.checkPassword()){
            //모델에 있는 패스워드 리스트 길이가 4이고, 모델의 비밀번호 체크하는 함수가 참일때.
            viewInterface.checkPassWordMessage()
        }
    }
}</code></pre><h4 id="2-뷰-인터페이스-생성">2) 뷰 인터페이스 생성</h4>
<p>(ViewInterface)
단어의 의미 그대로 뷰의 요소들을 나타내는 클래스나 인터페이스의 집합을 의미한다.
뷰를 관리하는 함수를 정리해놓는 공간이라 생각하면 쉽다.</p>
<pre><code>interface ViewInterface {
    fun toastMessage(i : Int)
    fun checkPassWordMessage()
    //누른 버튼의 숫자와 pw가 맞을 시 띄울 토스트 메세지의 함수.
}</code></pre><h4 id="3-model">3) Model</h4>
<p>데이터를 가공하는 관리 역할.</p>
<pre><code>class Model {
    var password : MutableList&lt;Int&gt; = mutableListOf()
    //변형 가능한 password 리스트 생성

    fun inputPassword(i : Int) {
        if (password.size &lt; 4) {
            password.add(i)
        }
    }
    fun checkPassword() : Boolean {
        var trueCount = 0
        var savePassword = mutableListOf(1, 2, 3, 4)

        for (i in 0 until savePassword.size) {
            if (savePassword.get(i) == password.get(i)) {
                trueCount += 1
            }
        }

        return trueCount == 4
    }
}</code></pre><h4 id="4-mainactivity">4) MainActivity</h4>
<pre><code>class MainActivity : AppCompatActivity(), ViewInterface {

    private lateinit var binding : ActivityMainBinding

    var presenter = Presenter(this)
        //this: 현 클래스, 여기선 현 클래스의 ViewInterface를 뜻함.

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        //데이터바인딩을 사용해 현재 액티비티 컨텐츠뷰로 설정. 바인딩 -&gt; UI요소와 액티비티 코드를 연결하는 객체가 됨.

        binding.mainActivity = this
        //데이터 바인딩으로 레이아웃을 변수랑 연결, mainActivity 변수를 현재 액티비티 객체로 설정.
        //레이아웃파일 mainActivity를 현재 액티비티 객체와 연결.
    }

    fun clickNumber (i: Int) {
        presenter.clickNumber(i)
        //클릭했을 때 무엇을 클릭했는지 넘겨줌.
    }

    override fun toastMessage(i: Int) {
        Toast.makeText(this, &quot;$i 번을 클릭했습니다.&quot;, Toast.LENGTH_SHORT).show()
    }

    override fun checkPassWordMessage() {
        binding.messageSuccess.visibility = View.VISIBLE
    }


}</code></pre><h1 id="👉-마무리">👉 마무리</h1>
<p>다음 글은 MVMM 패턴 정리할게요! 여러 패턴들을 어느 상황에 어떻게 적절히 사용할 수 있을지 아는것이 가장 중요한것 같습니다. 아직 저는 바로 판단하기는 힘들지만.. 연습과 실행.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Android Studio] 프래그먼트]]></title>
            <link>https://velog.io/@hui__ii/Android-Studio-%ED%94%84%EB%9E%98%EA%B7%B8%EB%A8%BC%ED%8A%B8</link>
            <guid>https://velog.io/@hui__ii/Android-Studio-%ED%94%84%EB%9E%98%EA%B7%B8%EB%A8%BC%ED%8A%B8</guid>
            <pubDate>Mon, 14 Aug 2023 04:36:28 GMT</pubDate>
            <description><![CDATA[<h1 id="fragment">Fragment</h1>
<h6 id="안드로이드에서-화면을-전환하는-방법은-두-가지가-있다">안드로이드에서 화면을 전환하는 방법은 두 가지가 있다.</h6>
<h6 id="1-새로운-액티비티를-띄우는-방식-2-액티비티의-일부만-바꾸는-방식프래그먼트">1. 새로운 액티비티를 띄우는 방식, 2. 액티비티의 일부만 바꾸는 방식(프래그먼트)</h6>
<p><img src="https://velog.velcdn.com/images/hui__ii/post/17e04ec2-d9fd-4654-8c9a-5655202b4e1b/image.png" alt=""></p>
<p>프래그먼트란, 액티비티(Activity) 내에서 <strong>재사용 가능한 모듈 혹은 UI 구성 요소</strong>이다.</p>
<p>액티비티 전환은 전체화면이 새롭게 그려지는 반면, 프래그먼트는 하나의 액티비티 내에서 일부분을 교체하여 화면을 구성의 변화를 주기 때문에 조각화면(fragment) 으로도 구성할 수 있어 더 적은 리소스와 시간을 사용하여 원하는 결과를 얻을 수 있다. </p>
<h3 id="특징">특징</h3>
<ul>
<li><p>여러개의 프래그먼트를 하나의 액티비티에 조합하여 여러 UI를 구축 가능.</p>
</li>
<li><p><strong>자체 라이프 사이클(생명주기)</strong>를 갖고 있어, 액티비티와 독립적으로 코드를 관리 가능.
(액티비티에서 그려지는 것이기 때문에 독자적으로 사용은 불가. 액티비티나 프래그먼트 뷰 계층에 속한다.)</p>
</li>
<li><p>프래그먼트를 사용하면 <strong>한 화면의 일부분을 다른 화면에서도 사용</strong>할 수 있게 되어, 화면 구성의 재사용성이 높아짐. </p>
</li>
<li><p>앱의 구조를 프래그먼트 단위로 나눠 관리할 수 있어 모듈화가 되며, 이를 통해 각 모듈별로 쉽게 수정하거나 업데이트할 수 있어 유지 보수가 더 편리.</p>
</li>
</ul>
<h3 id="">+</h3>
<ul>
<li>Activity가 Fragment를 포함하고 있고, Fragment가 또 다른 하위 Fragment를 가질 때가 있다. 이때 호스트하는 쪽은 <strong>FragmentManager</strong>라는 클래스의 객체로 하위 <strong>Fragment들을 관리</strong>할 수 있다.</li>
</ul>
<ul>
<li><p>Fragment는 호스팅한 Activity나 Fragment가 Started거나 이상인 경우에 Fragment를 추가, 교체, 삭제할 수 있고, 이 과정에서 생명주기를 갖는다.</p>
</li>
<li><p>이렇게 <strong>추가, 교체, 삭제된 기록</strong>들은 FragmentManager로 의해 백스택에 저장된다.</p>
</li>
</ul>
<blockquote>
<p>프래그먼트 생명주기
<img src="https://velog.velcdn.com/images/hui__ii/post/5b5e88e2-a7aa-4f66-bb84-245bd70dc0d7/image.png" alt=""></p>
</blockquote>
<h1 id="👉-사용법">👉 사용법</h1>
<p>어떤 버튼을 눌렀을 때, (<strong>액티비티 -&gt; 프래그먼트</strong>) (<strong>프래그먼트 -&gt; 프래그먼트</strong>) 로 이동시키는 간단한 예제를 준비해보았다.</p>
<h4 id="프래그먼트-뷰-바인딩">프래그먼트 뷰 바인딩</h4>
<pre><code>ex)

val binding = Fragment1Binding.inflate(inflater, container, false)
//뷰 바인딩 설정.


binding.myButton.setOnClickListener {...}
//바인딩 사용


return binding.root
//레이아웃 뷰 반환. 
//onCreateView() 메소드에서 반환하는 뷰를 화면에 띄우게 된다.


//현재는 onCreateView() 내부에서 binding 변수를 만들어 지역변수 처럼 사용하고 있지만 
lateinit 등을 활용해 전역변수로 선언해 사용해도 된다.</code></pre><h4 id="프래그먼트-간의-화면전환">프래그먼트 간의 화면전환</h4>
<blockquote>
<p><strong>FragmentManager</strong> : 백스택 관리, FragmentTransaction 등을 생성하는 클래스.</p>
</blockquote>
<blockquote>
<p><strong>FragmentTransaction</strong> : Android Jetpack Fragment 라이브러리에서 제공하는 클래스로 프래그먼트를 &#39;추가, 교체, 삭제&#39; 작업을 제공. 프래그먼트 백 스택관리, 프래그먼트 전환 애니메이션 설정가능.</p>
</blockquote>
<pre><code>//바인딩을 사용해 레이아웃의 버튼을 눌렀을 때, 
만들어놓은 프래그먼트로 넘어가게 만드는 코드이다.

...
binding.togoFragment1.setOnClickListener{
            val fragment1 = Fragment1()
        supportFragmentManager
               .beginTransaction()
               .add(R.id.framelayout, fragment1)
               .commit()
        }
... 

//supportFragmentManager를 사용하여 지원 라이브러리의 FragmentManager에 접근하고, 
프래그먼트 트랜잭션을 시작하고 관리할 수 있다.

</code></pre><h1 id="👉-마무리">👉 마무리</h1>
<p>친구들과 협업할 때 버스타지 않고 함께 개발하고 싶다는 생각과
발전의 흥미로 천천히 연습한 것을 기록해 봅니다 ✍️
더하여서 계획하는 프로젝트에 한 걸음 더 나아가고파요.</p>
<p>프래그먼트를 활용하는 jetpack Navigation 라이브러리 정리도 조만간 해볼게요.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Android Studio] 아키텍처 패턴과 MVC 에 대하여.]]></title>
            <link>https://velog.io/@hui__ii/Android-Studio-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-%ED%8C%A8%ED%84%B4%EA%B3%BC-MVC-%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC</link>
            <guid>https://velog.io/@hui__ii/Android-Studio-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-%ED%8C%A8%ED%84%B4%EA%B3%BC-MVC-%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC</guid>
            <pubDate>Sun, 13 Aug 2023 15:00:01 GMT</pubDate>
            <description><![CDATA[<h1 id="아키텍처-패턴">아키텍처 패턴</h1>
<p>(Architecture Pattern)</p>
<p>아키텍처란, 시스템을 구성하는 서브 시스템, 컴포넌트와 같이 구성요소 간의 관계를 관리하는 시스템의 구조.
재사용 가능한 설계 원칙을 제공하여 유지 보수 가능하고 확장 가능한 시스템을 만드는데에 도움을 주며, MVC, MVP, MVMM 이 이에 속한다.</p>
<h4 id="디자인-패턴과의-차이는-뭘까">디자인 패턴과의 차이는 뭘까.</h4>
<p>비슷하게 사용하는듯한 &#39;디자인 패턴&#39; 과 같은지 궁금해서 찾아보니 <strong>디자인 패턴</strong>은 주로 개별 클래스나 객체 간의 상호작용을 개선하는 데 사용되며, 코드 수준에서 적용되는 반면, <strong>아키텍처 패턴</strong>은 전체 소프트웨어 시스템의 구조와 구성 요소 간의 관계를 설계하고, 시스템의 큰 틀을 결정하는 데 사용된다고 한다.</p>
<h1 id="mvc">MVC</h1>
<p>(Model-View-Controller)
<img src="https://velog.velcdn.com/images/hui__ii/post/974beb5f-c582-4d95-a7d6-4b2bb19f5469/image.png" alt=""></p>
<p>모델은 애플리케이션의 정보(데이터)를 나타내며, 뷰는 텍스트, 체크박스 항목 등과 같은 사용자 인터페이스 요소를 나타내고, 컨트롤러는 데이터와 비즈니스 로직 사이의 상호동작을 관리한다. 
<br></p>
<ul>
<li><p><strong>Model</strong>
Model은 Data와 애플리케이션이 무엇을 할 것인지를 정의하는 부분으로,
컨트롤러가 호출을 하면 DB와 연동하여 사용자의 입출력 데이터를 다루는 일과 같은 <strong>데이터와 연관된 비즈니스 로직을 처리하는 역할</strong>을 한다. (데이터 추출, 저장, 삭제, 업데이트)</p>
</li>
<li><p>** View**
View는 사용자에게 보여주는 화면 부분. <strong>사용자와 상호작용 하며 컨트롤러로부터 받은 모델의 결과값을 화면으로 출력하는 역할</strong>을 한다.  </p>
</li>
<li><p><strong>Controller</strong>
Controller는 Model과 View 사이를 이어주는 인터페이스로 <strong>Model이 데이터를 어떻게 처리할지 알려주는 역할</strong>이다. 사용자로부터 View에 요청이 있으면 Controller는 해당 일을 수행하는 Model을 호출하고 Model이 업무를 모두 수행하면 다시 결과를 View에 전달한다.</p>
<br>
</li>
<li><p>MVC패턴 사용의 장점과 단점.<br>
구현하기 쉽고 단순하며 모델과 뷰과 분리되어 모델의 비종속성으로 재사용이 가능하다.<br>
위 사진과 같이 모델과 뷰가 컨트롤러를 통해 상호작용하기 때문에 새로운 모델과 뷰를 조합하여 사용하는데 유연하지 못할 수 있다. <br>
스파게티 코드들을 양산하게 되고 단순하게 파악할 수 있다는 장점이 하나의 클래스에 집중이 되면서 단점으로 바뀔 수도 있다.</p>
</li>
</ul>
<hr>
<h1 id="👉-예제">👉 예제</h1>
<p><a href="https://www.youtube.com/watch?v=FwFIKRpSElo">https://www.youtube.com/watch?v=FwFIKRpSElo</a> 를 보고 만들었다.
지정해둔 비밀번호를 올바르게 눌러 넣었을시 성공 토스트 메세지를 띄우는 예제이다.</p>
<p>build.gradle에 데이터바인딩, 뷰바인딩 권한 활성화 시키기 필수.</p>
<h4 id="1-레이아웃-구성">1) 레이아웃 구성</h4>
<pre><code>
&lt;LinearLayout
        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;&gt;

        &lt;GridLayout
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:columnCount=&quot;3&quot;
            android:rowCount=&quot;3&quot;&gt;

            &lt;androidx.appcompat.widget.AppCompatButton
                android:layout_width=&quot;100dp&quot;
                android:layout_height=&quot;100dp&quot;
                android:onClick=&quot;@{()-&gt; MainActivity.clickNumber(1)}&quot; 
                android:text=&quot;1&quot; /&gt;
                 &lt;!--  @{..} -&gt;  : 람다식을 사용하여 표현식을 정의한 것. 
            MainActivity 클래스의 clickNumber 메서드를 호출하고 인자로 1을 전달하는 코드--&gt;

            &lt;androidx.appcompat.widget.AppCompatButton
                android:layout_width=&quot;100dp&quot;
                android:layout_height=&quot;100dp&quot;
                android:onClick=&quot;@{()-&gt; MainActivity.clickNumber(2)}&quot;
                android:text=&quot;2&quot; /&gt;

            &lt;androidx.appcompat.widget.AppCompatButton
                android:layout_width=&quot;100dp&quot;
                android:layout_height=&quot;100dp&quot;
                android:onClick=&quot;@{()-&gt; MainActivity.clickNumber(3)}&quot;
                android:text=&quot;3&quot; /&gt;

            &lt;androidx.appcompat.widget.AppCompatButton
                android:layout_width=&quot;100dp&quot;
                android:layout_height=&quot;100dp&quot;
                android:onClick=&quot;@{()-&gt; MainActivity.clickNumber(4)}&quot;
                android:text=&quot;4&quot; /&gt;

            &lt;androidx.appcompat.widget.AppCompatButton
                android:layout_width=&quot;100dp&quot;
                android:layout_height=&quot;100dp&quot;
                android:onClick=&quot;@{()-&gt; MainActivity.clickNumber(5)}&quot;
                android:text=&quot;5&quot; /&gt;

            &lt;androidx.appcompat.widget.AppCompatButton
                android:layout_width=&quot;100dp&quot;
                android:layout_height=&quot;100dp&quot;
                android:onClick=&quot;@{()-&gt; MainActivity.clickNumber(6)}&quot;
                android:text=&quot;6&quot; /&gt;

            &lt;androidx.appcompat.widget.AppCompatButton
                android:layout_width=&quot;100dp&quot;
                android:layout_height=&quot;100dp&quot;
                android:onClick=&quot;@{()-&gt; MainActivity.clickNumber(7)}&quot;
                android:text=&quot;7&quot; /&gt;

            &lt;androidx.appcompat.widget.AppCompatButton
                android:layout_width=&quot;100dp&quot;
                android:layout_height=&quot;100dp&quot;
                android:onClick=&quot;@{()-&gt; MainActivity.clickNumber(8)}&quot;
                android:text=&quot;8&quot; /&gt;

            &lt;androidx.appcompat.widget.AppCompatButton
                android:layout_width=&quot;100dp&quot;
                android:layout_height=&quot;100dp&quot;
                android:onClick=&quot;@{()-&gt; MainActivity.clickNumber(9)}&quot;
                android:text=&quot;9&quot; /&gt;
        &lt;/GridLayout&gt;

        &lt;TextView
            android:id=&quot;@+id/message_success&quot;
            android:layout_width=&quot;wrap_content&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:text=&quot;비밀번호 언락 성공&quot;
            android:visibility=&quot;invisible&quot; /&gt;

    &lt;/LinearLayout&gt;
&lt;/layout&gt;</code></pre><p>그리드 레이아웃으로 금고모양 처럼 9개의 버튼 생성하였다.
후에 LinearLayout 위에 alt + enter를 눌러 데이터 태그를 만든다.
이 부분은 데이터 바인딩을 통해 XML 레이아웃 파일에서 사용될 변수를 정의한다.</p>
<pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;layout 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;&gt;

    &lt;data&gt;

        &lt;variable
            name=&quot;MainActivity&quot;
            type=&quot;com.example.a230811_mvvm.MainActivity&quot; /&gt;
        &lt;!--        xml레이아웃 파일에서 사용할 뷰 정의--&gt;
    &lt;/data&gt;
    &lt;!--    데이터 바인딩(Data Binding) 라이브러리를 사용할 때 XML 레이아웃 파일에서 데이터와 뷰를 연결--&gt;
    &lt;!--    &lt;variable&gt; -&gt; 뷰에서 사용될 변수 선언, 이름과 타입을 정함.  =&gt; 레이아웃 파일 내에서 뷰와 데이터를 연결하는데 사용.--&gt;
</code></pre><h4 id="2-mainactivity">2) MainActivity</h4>
<pre><code>//controller
class MainActivity : AppCompatActivity() {

    private lateinit var binding : ActivityMainBinding

    var model = Model()
    //모델 인스턴스 변수. 

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        //데이터바인딩을 사용해 현재 액티비티 컨텐츠뷰로 설정. 바인딩 -&gt; UI요소와 액티비티 코드를 연결하는 객체가 됨.
        binding.mainActivity = this
        //데이터 바인딩으로 레이아웃을 변수랑 연결, mainActivity 변수를 현재 액티비티 객체로 설정.
    }


    fun clickNumber (i: Int) {
        Toast.makeText(this, &quot;$i 번을 클릭했습니다.&quot;,Toast.LENGTH_SHORT).show()
        model.inputPassword(i)

        if(model.password.size == 4 &amp;&amp; model.checkPassword()) {
            //모델의 입력패스워드 사이즈가 4이고 입력한 패스워드가 일치할때
            binding.messageSuccess.visibility = View.VISIBLE
        }
    }
</code></pre><p>DataBindingUtil 클래스로 레이아웃을 설정하고 데이터 바인딩을 초기화한다.
현재 액티비티의 컨텍스트(this)와 레이아웃 리소스ID(R.layout.activity_main)를 전달받아 데이터 바인딩을 설정하고 바인딩 객체를 생성해 준다.</p>
<p>모델을 사용하는 부분은 모델 클래스 생성 후 작성하면 된다. -&gt; mvc 패턴완성!</p>
<h4 id="3-model-클래스-생성">3) Model 클래스 생성</h4>
<p>뷰를 표시해주는데 정보를 관리하는 일종의 클래스라 생각하면 쉽다.</p>
<pre><code>class Model {
    var password : MutableList&lt;Int&gt; = mutableListOf()

//패스워드 사이즈가 4미만 일때까지 입력 수 추가 o
    fun inputPassword(i : Int) {
        if (password.size &lt; 4) {
            password.add(i)
        }
    }

//정해 둔 비밀번호와 사용자가 입력한 비밀번호가 같은지 for문을 통해 
//숫자 하나하나 확인하고 trueCount가 4일시 true를 반환한다.

    fun checkPassword() : Boolean {
        var trueCount = 0
        var savePassword = mutableListOf(1, 2, 3, 4)

        for (i in 0 until savePassword.size) {
            if (savePassword.get(i) == password.get(i)) {
                trueCount += 1
            }
        }

        return trueCount == 4
    }
}</code></pre><p>true를 반환하는 경우, 이 함수를 호출한 MainActivity로 돌아가 입력한 값의 사이즈와 trueCount가 같은지 확인하고 <code>비밀번호 언락 성공</code> 텍스트뷰를 보이도록 한다.</p>
<h1 id="👉-마무리">👉 마무리</h1>
<p>데이터 태그 출현에 버벅거리는걸 보아선 다시 한 번 복습해야겠다.
남은 MVP, MVMM 아키텍처 패턴도 예제랑 같이 정리해보기를 목표로 하며.. zz</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Android Studio] 엑티비티 뷰 바인딩]]></title>
            <link>https://velog.io/@hui__ii/Android-Studio-%EB%B7%B0-%EB%B0%94%EC%9D%B8%EB%94%A9</link>
            <guid>https://velog.io/@hui__ii/Android-Studio-%EB%B7%B0-%EB%B0%94%EC%9D%B8%EB%94%A9</guid>
            <pubDate>Thu, 27 Jul 2023 15:03:52 GMT</pubDate>
            <description><![CDATA[<h1 id="viewbinding의-정의">ViewBinding의 정의</h1>
<p>findViewById() 메서드를 사용하지 않아도 레이아웃 파일을 기반으로하는 액티비티나 프래그먼트를 클래스 안 뷰에 참조 변수를 직접 할당할 수 있다. 뷰 바인딩은 안드로이드 데이터 바인딩과는 다른 기술이므로 혼동하지 않도록 주의!</p>
<h1 id="👉-viewbinding-예제">👉 ViewBinding 예제</h1>
<p>뷰 바인딩을 사용해 버튼을 누르면 토스트 메세지가 나오게 만들기.
(MainActivity, Fragment 에서 바인딩 방법이 다르기 때문에 두 가지로 해보겠습니다.)</p>
<h3 id="레이아웃에-버튼-만들기">레이아웃에 버튼 만들기</h3>
<p>Activity에 맞는 레이아웃에서 설정.</p>
<pre><code class="language-kotlin">&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;&gt;

//    id 설정을 해줘야 바인딩 가능
    &lt;androidx.appcompat.widget.AppCompatButton
        android:id=&quot;@+id/IdButton&quot;
        android:layout_width=&quot;300dp&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:text=&quot;클릭 시, 토스트 메세지&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot;
        app:layout_constraintBottom_toBottomOf=&quot;parent&quot;
        app:layout_constraintStart_toStartOf=&quot;parent&quot;
        app:layout_constraintEnd_toEndOf=&quot;parent&quot; /&gt;

&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;</code></pre>
<h3 id="1-viewbinding-활성화">1) viewBinding 활성화</h3>
<p>Gradle Scripts &gt; build.gradle(Module: 프로젝트명) </p>
<pre><code class="language-kotlin">android {
    // ..
    buildFeatures {
        viewBinding true
    }
}</code></pre>
<p>위 코드를 작성 후 <strong>Sync Now</strong> 라는 메시지를 클릭해 그래들 수정을 확정.</p>
<h3 id="2-activity-에서-바인딩">2) Activity 에서 바인딩</h3>
<pre><code class="language-kotlin">import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
import com.example.a230727_viewbinding.databinding.ActivityMainBinding

private lateinit var binding: ActivityMainBinding

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //(1) 바인딩 생성
        val binding = ActivityMainBinding.inflate(layoutInflater);
        //(2) 최상위 레이아웃 표시
        setContentView(binding.root)

        //뷰 바인딩으로 버튼 접근
        binding.IdButton.setOnClickListener() {
            toast(&quot;버튼이 클릭 되었습니다.&quot;)
        }

    }
    fun toast(message: String){
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }

}</code></pre>
<ul>
<li><p>(1) 바인딩 초기화 : <strong>val binding = ActivityMainBinding.inflate(layoutInflater)</strong></p>
<p>레이아웃 파일명의 첫글자와 언더바( _ ) 다음 글자를 대문자로 바꾸고 (activity_login -&gt; ActivityLogin), 
뒤에 Binding을 붙여 바인딩 생성하고, inflate 메서드는 인자로 전달된 레이아웃 파일을 기반으로 layoutInflater을 활용해 뷰 계층 구조를 만든다.</p>
<br/></li>
<li><p>(2) 레이아웃에 표시 : <strong>setContentView(binding.root)</strong></p>
<p>최상위 뷰로 레이아웃을 설정한다. </p>
</li>
</ul>
<h1 id="👉-마무리">👉 마무리</h1>
<p> 프래그먼트 바인딩도 조만간 정리하겠습니다~!!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Android Studio] 리사이클러뷰]]></title>
            <link>https://velog.io/@hui__ii/Android-Studio-%EB%A6%AC%EC%82%AC%EC%9D%B4%ED%81%B4%EB%9F%AC%EB%B7%B0</link>
            <guid>https://velog.io/@hui__ii/Android-Studio-%EB%A6%AC%EC%82%AC%EC%9D%B4%ED%81%B4%EB%9F%AC%EB%B7%B0</guid>
            <pubDate>Thu, 27 Jul 2023 07:02:25 GMT</pubDate>
            <description><![CDATA[<h1 id="recyclerview의-정의">RecyclerView의 정의</h1>
<p>RecyclerView란 &#39;A flexible view for providing a limited window into a large data set&#39; 으로
한 화면에 표시할 수 없는 <strong>많은 데이터를 스크롤 가능한 리스트로 표시해주는 위젯</strong>이다.</p>
<p>리사이클러뷰는 <strong>뷰홀더 패턴</strong>을 사용하여 화면 밖으로 스크롤된 아이템 뷰를 메모리에 유지하고 재사용할 수 있는데, 이를 통해 불필요한 뷰 객체 생성과 파괴를 줄여 성능과 메모리 사용량을 개선하기 때문에 많은 데이터도 리스트 처럼 담을 수 있는 것이다.</p>
<p>목록을 구성하는데 사용되는 뷰로는 ListView 도 있지만 성능상 최근엔 RecyclerView를 더 선호하는 편이다. 주요클래스로 특징을 살펴보자!</p>
<h3 id="주요클래스">주요클래스</h3>
<pre><code>Adapter : 기존의 ListView에서 사용하는 Adapter와 같은 개념으로 데이터와 아이템에 대한 View 생성.
ViewHolder : 재활용 View에 대한 모든 서브 뷰를 보유.
LayoutManager : 아이템 항목을 어떻게 배치하는가를 결정.
ItemDecoration : 아이템에 대한 데코레이션(경계선, 여백, 그림자 등) 을 제공하는 클래스.
ItemAnimation : 아이템 항목이 추가, 삭제되거나 정렬될 때 애니메이션 처리.</code></pre><ul>
<li><p><strong>Adapter</strong> : 데이터를 가져와 레이아웃에 적절하게 바인딩하는 역할의 클래스.</p>
<ul>
<li>getItemCount() : 리사이클러뷰에 전달되는 데이터의 개수를 반환.</li>
<li>onCreateViewHolder() : 뷰홀더 객체를 생성. 목록 아이템에 사용되는 레이아웃을 인플레이션하고, 뷰홀더 객체를 생성한 후 반환.</li>
<li>onBindViewHolder() : 데이터를 뷰에 바인딩. 어댑터는 전달된 데이터를 사용하여 각 위치에 해당하는 목록 아이템의 뷰에 표시되는 값을 업데이트.</li>
</ul>
</li>
<li><p>*<em>ViewHolder  *</em> : 아이템의 뷰(View)를 저장하고 관리하는 도구</p>
<ul>
<li>아이템에 대한 모든 뷰 객체를 저장해두기 때문에, 뷰 객체를 계속 찾아야 하는 findViewById()를 반복적으로 호출하지 않아도 된다. 목록 아이템을 표시하는 데 필요한 뷰를 빠르게 가져오고 화면에 표시 가능. &gt; 더욱 빠르게 스크롤, 렌더링. 무한 스크롤 구현 가능.</li>
</ul>
</li>
<li><p><strong>LayoutManger</strong> </p>
<ul>
<li>더 다양한 타입의 리스트들을 지원하고, 커스텀할 수 있도록 해준다.</li>
</ul>
</li>
</ul>
<h1 id="👉-recyclerview-예제">👉 RecyclerView 예제</h1>
<h3 id="1-아이템-레이아웃-생성">1) 아이템 레이아웃 생성</h3>
<p><img src="https://velog.velcdn.com/images/hui__ii/post/76e99a43-2875-4005-8d0e-5e461ddcbd77/image.png" alt=""></p>
<p><strong>item_recycler_view.xml</strong></p>
<pre><code class="language-kotlin">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;androidx.constraintlayout.widget.ConstraintLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;wrap_content&quot;
    android:layout_margin=&quot;5dp&quot;
    android:paddingVertical=&quot;10dp&quot;
    android:paddingHorizontal=&quot;10dp&quot;
    android:background=&quot;@color/purple&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;&gt;

    &lt;TextView
        android:id=&quot;@+id/tv_name&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:text=&quot;이름&quot;
        android:textStyle=&quot;bold&quot;
        android:layout_marginLeft=&quot;20dp&quot;
        android:textSize=&quot;24sp&quot;
        android:textColor=&quot;@color/black&quot;
       app:layout_constraintLeft_toLeftOf=&quot;parent&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot;/&gt;
    &lt;TextView
        android:id=&quot;@+id/tv_age&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:text=&quot;나이&quot;
        android:layout_marginLeft=&quot;20dp&quot;
        android:textSize=&quot;18sp&quot;
        android:textColor=&quot;@color/black&quot;
        app:layout_constraintLeft_toLeftOf=&quot;parent&quot;
        app:layout_constraintTop_toBottomOf=&quot;@+id/tv_name&quot; /&gt;

&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;</code></pre>
<hr>
<p>res &gt; values &gt; color.xml 에서 배경에 넣을 색 값을 추가. (전 연보라색 했습니다!!)</p>
<pre><code class="language-kotlin">    &lt;color name=&quot;purple&quot;&gt;#E8CCFF&lt;/color&gt;

</code></pre>
<h3 id="2-데이터-클래스-생성">2) 데이터 클래스 생성</h3>
<p><strong>BoardItem.kt</strong></p>
<pre><code class="language-kotlin">data class BoardItem(val name: String, val age: String)</code></pre>
<p> 리스트의 각 아이템의 내용이 담길 <strong>데이터 클래스</strong>를 만듭니다. 
 <br/></p>
<h3 id="3-리사이클러뷰-어댑터-생성">3) 리사이클러뷰 어댑터 생성</h3>
<pre><code class="language-kotlin">class BoardAdapter(val itemList: ArrayList&lt;BoardItem&gt;) :
    RecyclerView.Adapter&lt;BoardAdapter.BoardViewHolder&gt;() {

//    viewGroup : 다른 뷰들을 포함하는 컨테이너 역할의 클래스. (linearLayout, RelativeLayout, FrameLayout..)
//    context : 액티비티, 서비스 컴포넌트가 이를 상속받음 -&gt; 실행앱 정보, 리소스 접근 ..
//    LayoutInflater : 안드로이드에서 XML 레이아웃 파일을 실제 뷰 객체로 인플레이션하는 역할의 클래스

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BoardViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.item_recycler_ex, parent, false)
//R.layout.item_recycler_ex &lt;-를 parent.context에서 인플레이션하여 뷰 객체(view) 생성.            

        return BoardViewHolder(view)

    }

    override fun onBindViewHolder(holder: BoardViewHolder, position: Int) {
        holder.tv_age.text = itemList[position].age
        holder.tv_name.text = itemList[position].name
//    ViewHolder의 tv_age라는 TextView의 텍스트를 itemList에서 해당 position에 있는 아이템의 나이(age)로 설정합니다.
//onCreateViewHolder 는 리사이클러 뷰가 생성될 때만 호출되지만, onBindViewHolder 는 스크롤 할때마다 호출이 된다.
    }

    override fun getItemCount(): Int {
        return itemList.count()
    }
//  RecyclerView에 표시할 아이템의 개수를 반환 = 위 클래스에서 매개변수로 받은 itemList 의 길이


    inner class BoardViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val tv_age = itemView.findViewById&lt;TextView&gt;(R.id.tv_age)
        val tv_name = itemView.findViewById&lt;TextView&gt;(R.id.tv_name)
    }
}</code></pre>
<p>onCreateViewHolder, BoardViewHolder, getItemCount 클래스를 <strong>오버라이딩</strong> 합니다.
(RecyclerView.Adapter&lt;BoardAdapter.BoardViewHolder&gt;() 의 기능을 상속받는 &quot;BoardAdapter&quot; 를 사용하기 위함)</p>
<pre><code>onCreateViewHolder -&gt; 아이템 레이아웃과 결합 
onBindBiewHolder -&gt; view 에 내용입력
getItemCount -&gt; 리스트내 아이템 갯수
BoardViewHolder -&gt; 레이아웃 내 View 연결</code></pre><h3 id="4-xml-에-리사이클러뷰-넣기">4) xml 에 리사이클러뷰 넣기</h3>
<p><strong>activity_main.xml</strong>
<img src="https://velog.velcdn.com/images/hui__ii/post/7f8efdd0-f93a-4fbe-8ca8-80ee500ffa97/image.png" width="30%" height="30"></p>
<pre><code class="language-kotlin">&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;&gt;

    &lt;androidx.recyclerview.widget.RecyclerView
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;match_parent&quot;
        android:id=&quot;@+id/profile&quot;

        app:layoutManager=&quot;androidx.recyclerview.widget.LinearLayoutManager&quot;
        android:orientation=&quot;vertical&quot;
        tools:listitem=&quot;@layout/item_recycler_ex&quot;
        app:layout_constraintTop_toTopOf=&quot;parent&quot;
        app:layout_constraintLeft_toLeftOf=&quot;parent&quot;
        app:layout_constraintRight_toRightOf=&quot;parent&quot; /&gt;
    &lt;!-- listitem : 리사이클러뷰에 리스트 아이템으로 item_recycler_ex(낱개) 넣음--&gt;

&lt;/androidx.constraintlayout.widget.ConstraintLayout&gt;</code></pre>
<p>가로방향으로 배치하려면 vertical을 horizontal로 바꾸면 된다.
만약 격자무늬로 배치하고 싶으면 LinearLayoutManager 대신 GridLayoutManager를 사용.
<br/></p>
<h3 id="5-리사이클러뷰에-어댑터-붙이기">5) 리사이클러뷰에 어댑터 붙이기</h3>
<p><strong>MainActivity.kt</strong></p>
<pre><code class="language-kotlin">class MainActivity : AppCompatActivity() {

    private lateinit var binding : ActivityMainBinding


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

//        &lt;&gt; : 실제 리스트에 저장될 데이터의 타입을 의미
        val rv_board = binding.profile

        val itemList = ArrayList&lt;BoardItem&gt;()


//      !! :  Kotlin에서 Nullable 타입을 Non-Nullable로 강제로 변환하는 연산자. null 값이 아님을 확신.

        itemList.add(BoardItem(&quot;예진&quot;, &quot;17세&quot;))
        itemList.add(BoardItem(&quot;지민&quot;, &quot;17세&quot;))
        itemList.add(BoardItem(&quot;예지&quot;, &quot;16세&quot;))
        itemList.add(BoardItem(&quot;현서&quot;, &quot;17세&quot;))
        itemList.add(BoardItem( &quot;소현&quot;, &quot;17세&quot;))
        itemList.add(BoardItem( &quot;기준&quot;, &quot;29세&quot;))
        itemList.add(BoardItem( &quot;수현&quot;, &quot;27세&quot;))
        itemList.add(BoardItem( &quot;상윤&quot;, &quot;32세&quot;))

//        ArrayList(itemList) 를 사용해 Adapter를 만든 후, notifyDataSetChange()로 어댑터와 리사이클러뷰를 갱신 시킨다. (다시 그려서 화면에 보여준다)
        val boardAdapter = BoardAdapter(itemList)
        boardAdapter.notifyDataSetChanged()

        rv_board.adapter = boardAdapter
        rv_board.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
//      레이아웃 매니저 설정 = 리사이클러뷰 안에 아이템들을 어떤 방식으로 배치할지를 결정
//         VERTICAL: 세로배치, HORIZONTAL: 가로배치 / false: 스크롤 역순x

    }
}</code></pre>
<h1 id="마무리">마무리</h1>
<p>참고자료 : <a href="https://uknowblog.tistory.com/29">https://uknowblog.tistory.com/29</a>
정리해도 어려운 것 같습니다.. 나중에 binding 활용해서 다시 한 번 도전해볼게요. 완성~!</p>
<p align="center"><img src="https://velog.velcdn.com/images/hui__ii/post/5e475de5-0a94-4a62-ab8b-1181112a809e/image.png" width="30%" height="30">











]]></description>
        </item>
    </channel>
</rss>