728x90

0. 토이 프로젝트를 진행하면서 알게된 것들에 대해서 정리하고 이를 누군가 봄으로써 편하길 바라며 정리합니다.
이 글에선 자바 코드와 코틀린 코드를 혼용하여 사용합니다.

1. 이전 글에 이어서 클릭 구현에 대해 알아봅니다.

2. 자바나 코틀린이나 코드 구현이 비슷함으로 보면서 전체 흐름을 이해하는 것을 추천드립니다.


메인 액티비티 xml에 리사이클러뷰를 설정한 모습
리사이클러뷰에 들어가는 list xml을 만들어준 모습

간단하게 텍스트뷰만 사용하여 만들었다. 실제 앱을 만든다면 조금 더 복잡하게 많은 것들이 들어간다.

1. 먼저 과일 이름을 넣은 배열을 하나 만들어본다.

2. 먼저 안드로이드 개발자 홈페이지에서 코드를 봅니다

developer.android.com/guide/topics/ui/layout/recyclerview?hl=ko

 

RecyclerView로 동적 목록 만들기  |  Android 개발자  |  Android Developers

RecyclerView로 동적 목록 만들기   Android Jetpack의 구성요소 RecyclerView를 사용하면 대량의 데이터 세트를 효율적으로 표시할 수 있습니다. 개발자가 데이터를 제공하고 각 항목의 모양을 정의하면 R

developer.android.com

코틀린으로는 init을 사용하여
자바는 getTextView()도 만들어준 모습이다.

또한 읽어보면 click listener를 ViewHolder에 구현하라고 적혀있다.

구글링이나 유튜브를 통해서 보다보면 코틀린으로 apply를 사용하여 아래 처럼 구현하기도 한다.

그렇지만 이 코드는 ViewHolder클래스 내에서 구현하는 것과 동일하기 때문에 Android Developer처럼 구현하면 된다.


여담

공지 관련 앱을 만들고 있다보니 RecycerView에 구현되어야하는 기능이 2가지가 있었다.

1. 왼쪽과 오른쪽 2가지의 RecycerView가 존재하고 각각 클릭시 주황색/푸른색으로 클릭 표시가 되어야한다.

이는 위와 찾아본 정보와 같이 ViewHolder클래스에 구현하면 쉽게 구현이 가능했다.

2. 왼쪽을 누를 때 오른쪽에 나오는 값이 변동되어야한다.
변동되어야하는 규칙
- 1. 간호대학을 선택시 간호학과가 나온다.
- 2. 동물생명과학을 누를 시 동물생명과학대학 학과들이 추가적으로 나온다.
즉, 왼쪽에 누르는 값이 변동되면서 오른쪽에 나오는 값들이 다중 선택되어 나타난다.

상단 2개 선택
1, 3 선택

어떻게 구현되어야할까?

먼저 보다보면 왼쪽 뷰 클릭시 오른쪽 뷰에 반영되는 것을 알 수 있다.
??????? 어떻게 다른 뷰에서 다른 뷰로 상호작용을 할 수 있을까?



반응형
728x90

토이 프로젝트를 진행하면서 알게된 것들에 대해서 정리하고 이를 누군가 봄으로써 편하길 바라며 정리합니다.
이 글에선 자바 코드와 코틀린 코드를 혼용하여 사용합니다.

RecyclerView를 배우게 된다면 ListView는 거들떠 보지도 않게 된다. 그런 이유는 RecyclerView를 배우다보면 ListView의 확장판처럼 느껴지기 때문이다. 그럼으로 ListView를 알면 RecyclerView에 대해 조금 더 알기 쉽게 된다.
그래서 먼저 ListView를 알아본다

LinearLayout에 자식뷰 추가하기

List View를 추가하여 사용하고 싶다면 아래 코드와 같이 3줄로 작성하면 된다. (물론 XML로 설정 해야한다.)
서브 리스트 작성 xml은 넘어가고 현재 아래 코드에선 phone_info 레이아웃이라고 생각해두면 된다.

LinearLayout contact_linearLayout = findViewById(R.id.contact_linearLayout);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.phone_info, contact_linearLayout, false);

 

코드의 두 번째 줄을 보면 System에 Service 객체를 요청하고 받는다.
이는 인자값에 들어가있는 Context.Layout_inflater_service란 이름으로 알 수 있듯이 레이아웃 리소스를 Inflate수 있도록 해준다.
=> Inflate가 무엇일까? 안드로이드에서 Inflate의 정의는 xml에 표기된 레이아웃들을 메모리에 객체화시키는 행동이다
간단하게 xml 레이아웃을 메모리화한다고 생각하자.

코드의 3번째 줄과 같이 View 타입의 view를 만들기 위해서 inflater객체의 inflate함수를 통해서 view를 만들 수 있다.

inflate함수에 들어가는 친구들을보면 R.layout.phone_info라는 xml을, contact_liearLayout이란 리니어레이아웃, false란 Boolean은 리니어레이아웃의 자식으로 붙일 것이냐 아니냐를 의미한다. 공식문서에서는 attachToRoot라고 한다.

정확한 정보는 아래 이미지와 같다

TextView name = view.findViewById(R.id.textView_name);
name.setText(data.getStringExtra("name"));
TextView number = view.findViewById(R.id.textView_phone_number);
number.setText(data.getStringExtra("number"));

만든 View에 대한 정보 추가는 위 코드와 같이 할 수있다.

우리가 만든 Infalter에 infalte명령을 내릴 때 false인자를 넣어주었다. 이는 attachToRoot에 해당하며 root View에 추가하지 않는다를 의미한다. --> 우리가 infalte한 View는 메모리에 올라가 있지만 ListView에 추가되어 있지 않다.

그럼으로 우리가 메모리에 있는 View를 ListView에 붙여줘야한다. 이에 해당하는 함수는 addView이다. 이 함수는 ViewGroup에 있는 함수이다. 우리는 현재 LiearLayout에 추가할 것이므로 아래 코드와 같이 작성한다.

contact_linearLayout.addView(vi);

addView에 대한 공식문서는 ViewGroup 페이지를 통해 할 수 있다.

developer.android.com/reference/android/view/ViewGroup#addView(android.view.View,%20android.view.ViewGroup.LayoutParams)

 

ViewGroup  |  Android 개발자  |  Android Developers

 

developer.android.com

이정도로 ListView를 커스텀하여 사용할 수 있다. Adapter로 사용하는 방법도 존재하지만 이는 설명하지않고 넘어간다.


RecyclerView 기본 구조

RecyclerView는 무조건 adapter를 이용하여 정보를 다룬다. 아직 adapter에 대해서 모른다면, 위키 정보를 읽어보면 조금 머리가 상쾌해질 것이다.

간단하게 결합도구?라고 생각해본다. 뭘 결합할까? -> 정보와 View와 결합해준다.
RecyclerView는 Adapter를 통해서 우리가 사용할 정보를 자식 View에 설정하여 추가한다. 그럼으로 adapter를 수행할 클래스를 하나 만들어줘야한다.
아래 adapter클래스 코드에서 볼 수 있듯이 17번째 줄 생성자를 통해서 List(array)를 adapter 내부에 가지고 있다.
코틀린에서는 생성자를 저렇게 적어줄 수 있다.
그리고 총 기본적인 3가지의 함수, 1개의 클래스가 필요한데 onCreateViewHolder, onBindViewHolder, getItemCount, Holder클래스다. 이름따라 생각하면 쉽다. 먼저 2개의 함수에 ViewHolder란 말이 붙어있음으로 ViewHolder부터 알아보자.

RecyclerView는 ViewHolder라는 패턴을 강제적으로 지키고 있기 때문에 ViewHolder가 필요하다
그렇기 때문에 inner class로 Holder란 클래스를 만들었고 RecyclerView의 ViewHolder를 상속받아 사용한다.
=> ViewHolder가 무엇인지 모를 수도 있다. findViewById란 함수는 View 계층에 따라 함수가 계속 반복되어 찾아서 느리다고 한다. <!-- 비용이 비싸다란 표현이 더 정확한 것 같다. --> 그래서 안드로이드에서 View Holder를 사용한다. 
이 ViewHolder에 대한 내용은 정확하지 않음으로 조금 더 신뢰할 수 있는 내용을 찾아 이해하길 바란다.
중요한 사실은 RecyclerView는 ViewHolder패턴을 강제적으로 지키기 때문에 ViewHolder 클래스를 inner class로 만들어 사용하고 있다는 것이다.

이제 adapter에 존재하는 첫번째 함수 onCreteViewHolder를 보면 ListView에서 알아보았던 것과 비슷한 것이 있다 아니 똑같은 것이 존재한다. 이제 하나씩 살펴본다.

from은 context를 받아 LayoutInflater를 반환하고 이를 가지고 infalte함수를 통해서 ListView와 같이 한다.
혼동할만한 요소는 parent이다. from함수로 넘겨준 값은 parent.context로 ViewGroup의 context를 가져온다.
ListView에서는 Context로 하였다. RecyclerView는 Activity에 존재하고 이는 parent의 ViewGroup이라고 생각할 수 있다.
onCreateViewHolder에서 결과적으로 ListView처럼 View를 만들고 Holder에 View를 넣어 Holder객체를 반환한다.
return 부분에서 새로 만든 Holder 객체는 위 코드 아래에 있는 inner class holder다.

LayoutInflater에서 쓰이는 from함수

번째 onBindViewHolder함수에서는 holder를 받는다. 무슨 Holder? 첫번째 함수에서 만든 holder다.
여기서 bind를 하는 건데 =>
bind가 뭘까? 연결해준다 정도로 간단하게 생각하고 익숙해져보자.

onBindViewHolder함수에서는 우리가 가진 정보를 ViewHolder(클래스)에서 만들어둔 View에 붙일 것이다.

Holder클래스에서 var collegeText: TextView = itemView.findViewById(R.id.CollegeName) 와 같이 변수에 xml를 연결시켜준다. 그리고 onBindVidwHolder 함수에서 holder란 인자를 이용하여 값을 지정할 수 있다.

여기서 한번 더 생각해볼 수 있는 것은 inner class holder의 ItemView다. 이 클래스의 ItemView는 무엇을 의미할까?
이는 onCreateViewHolder에서 만들었던 view를 의미한다. 즉, holder 클래스의 itemview는 onCreateViewHolder에서 만든 view를 의미하며 이 view는 현재 lsit_item_filter_college란 xml에서 만든 view들을 findViewById로 찾을 수 있게 된다.

20번째 줄에서 만든 View(현재 2번째줄)가 holder클래스 내에 있는 ItemView를 의미한다.


RecyclerView 클릭 구현

안드로이드에서 평소 클릭 구현은 어떻게할까? 쉽게 findViewById()를 통해서 xml가 연결하고 setOnClickListener 함수를 통해서 클릭 함수를 구현해왔다.

RecyclerView라고 다르게 구현할까? 같은 View이기때문에 동일하게 구현하면 된다.
하지만 기존과 다른 것은 어디에서 클릭 함수를 구현해야는지 모른다는 것이다.

차근 차근 생각해보자

0. Q: 클릭 리스너 함수를 어디서 구현할까?
    A: View에 구현할 수 있다.

1. 먼저 클릭 리스너는 View에서 사용가능하다. 그럼으로 View가 있는 곳에서 가능하다.
    Q: adapter내의 View가 어디에 존재할까?
    A: onCreateViwHolder에서의 view, holder클래스의 itemView, onBindViewHolder의 holder 객체 속 itemview가 존재한다.

2: Q: 어느 곳에서 클릭 리스너를 구현할까?
    A: onCreateViewHolder?, onBindViewHolder?, holder 클래스?

이렇게 구현할 수 있는 곳은 3가지로 어느 곳에서 작성하면 좋을지 모르겠다.
왜 모를까? 우리는 아직 각 함수내에서 진행되는 방식을 모르기때문이다. 그렇다면 내가 원하는 기능을 구현하기 위해서, 먼저 각 함수들이 무슨 일을 하는지 알아봐야한다.

 

 

그렇기 때문에 다음 글에선 각 함수에서 하는 일이 무엇이고, 어느 곳에서 클릭 함수가 진행되어야하는지 알아본다.
또한 두개의 RecyclerView를 활용하는 방법도 생각해본다.

참고:
Infalte: https://soo0100.tistory.com/1017[Thank you for everything in the world]
RecyclerView: wooooooak.github.io/android/2019/03/28/recycler_view/

반응형
728x90

학교 에타 커뮤니티를 통해서 개발, 디자이너 각 한분씩 구해서 이전에 진행하였던 공지사항 메일을 앱으로 변경하게 되었다. 그래서 진행하면서 인상적이었던 점을 하나씩 적어보려고한다.

디자이너가 구현한 이미지를 직접 안드로이드로 구현하는 것은 아주 쉬울 줄 알았다.
아니였다.

먼저 NEW라는 글씨가 정확하게 박스가 맞아들어가지 않아서 padding값을 구하기가 힘들었다.
또한 New의 border가 바깥쪽부터 값을 계산하기 때문에 정확한 border값을 구할 수 없었다.

두번째로 글씨체였다. Figma 사이트를 통해서 디자인 한 값들을 바로바로 확인하여 구현할 수 있도록 되어있었다.

NanumSquare_ac라고 되어있었는데 디자인한 분께 물어보니 Noto Sans 글씨체를 사용한다고 하셨다.

 

Noto Sans 글씨체

나눔스퀘어 글씨체

두 글씨체를 본다면 하나는 Noto Sans 경우 위로 공백이 너무 컸다. 그래서 일단 비슷한 글씨체인 나눔스퀘어 글씨체를 사용하였는데 이는 나중에 왜 그런지 이유를 찾아볼 생각이다.

위 이미지를 직접 구현해야하는 상황이었고 아래와 같이 안드로이드로 구현하였다.
완벽하게 동일하지 않다. 글씨체를 임의로 바꾼 것 때문에 차이가 난다고 생각한다.

또한 위를 처음엔 LinearLayout으로 만들었고, 이후 Layout에 가중치가 쌓이면 로딩시 느리다고 경고문이 떠 Relative Layout으로 수정하였다. 새로운 사실 감사합니다 😋

svg,png는 svg는 이번에 알게 되었고, png은 기존에 사용해서 투명 바탕을 때문에 사용함을 알고 있었다.
자연스럽게 png이미지를 가져와 사용했는데 background 색이 회색으로 계속 변해서 나왔다.
알고보니 background 색을 지정해줘야 한다는 것이었다. 와!

디자이너가 만든 이미지를 figma를 통해서 볼 때 어느정도 보기 편한 것도 필요하다고 느꼈다.( sp 단위, 각 view가 box에 맞게 들어가도록) 그리고 안드로이드 개발자도 이를 보고 동일하게 구현하는 것

결국 서로간의 어느정도 소통이 필요하고 배려가 필요한 문제라고 깨닫게 되었다.

반응형
728x90

문제 발단

 대학교에 다니면서 제일 중요한 것이 무엇일까? 바로 공지 사항이다.
대학교 공지사항은 여러가지 이유로 나에게 도움이 되는 정보들이 많이 올라온다. 그렇기 때문에 대학생이라함은 공지사항을 챙겨봐야한다. 나는 하루에 2-3번 정도 공지사항을 보기 위해서 자주 들어간다. 조금 많이 본다.
대학 공지사항을 한 페이지만 보면 그나마 괜찮지만, 페이지가 다른 공지사항을(대학, 과 공지 등) 볼 때 매우 귀찮은 일이다.
코딩을 배우는 이유는 귀찮은 일을 줄이기 위해서다. 그러므로 내가 보는 공지를 알림으로 띄우기로 마음먹었다.

데이터 얻어 오는 수단 1: 크롤링

 학교에서 API 제공해준다면 그 정보만을 이용해서 개발하면 그만이다. 사실 그러면 좋은데 문의를 올렸는데도 답장이 없고, 아는 형도 학교 페이지를 크롤링를 하여 상업적으로 이용해도 무관하다고 허락을 받았다고 했다. 그래서 일단 크롤링을 하기로 마음 먹었다. 나중에 API 요청해보고 안되면 그냥 크롤링으로 하려고 한다.

 크롤링은 웹 사이트의 내용을 긁어와 필요한 내용만 가져오는 것이라고 알고 있다. 이는 불법일 수도 불법이 아닐 수 있는 것들이다. 크롤링을 할 때 JS로 하든 파이썬으로 하든 상관이 없지만 그동안 해왔던 것이  파이썬 + 뷰티풀 수프이라 이번에도 사용했다. 하지만 내가 하고 있는 이 크롤링이 이게 크롤링이 맞는 건가라는 의구심이 들 수밖에 없었다. 아래 글을 읽어보는 것을 추천한다.

velog.io/@mowinckel/%EC%9B%B9-%ED%81%AC%EB%A1%A4%EB%A7%81-I

 

🏭 '웹 크롤러' 좀 그만 만들어라

아무튼 그만 만들어라.

velog.io

웹 크롤러 좀 그만 만들어라란 글을 보면 납득할 것이다. 나는 그러므로 그저 웹 페이지의 내용을 긁어왔다고 표현하고 싶다. 일단 웹 페이지 하나하나 긁어와서 내게 필요한 서비스의 데이터를 구축할 수 있게 되었다.
그냥 API를 지원해주면 좋겠다. 학생들을 위한 좋은 일이 아닐까..?

서비스 플랫폼 선택하기

 이제는 어떻게 알림을 보낼지를 결정해야 한다. 어떻게 학교 공지를 나에게 알림을 표시할까? 보통 많이 쓰이는 카카오, 페이스북 등 여러 가지 메신저가 존재한다. 이 중 뭐가 좋을까 생각을 하다 카카오는 API 사용함에 있어서 개발자에게 불친절하다고 생각이 들었고 페이스북은 내가 잘 쓰지 않고 그만 푸른 창에 들어가고 싶어 둘 다 싫었다. 싫은 것도 싫은 것이지만 봇을 만들기 시작하면 봇을 상시 켜 두어야 한다. 그러므로 AWS나 헤로쿠나 내 컴퓨터나 뭐든지 일단 켜 둬야 한다. 싫다. 어차피 하루에 2,3번 보는 공지 때문에 컴퓨터를 계속 켜 둬야 할까? 너무 낭비라고 생각했다.
 먼저 지정 시간에 컴퓨터를 자동으로 켜서 나에게 알림을 보낼 수 있는 것을 생각했다. 컴퓨터를 자동으로 이용하는 것에 적합한 것은 GitAction이라고 생각했다. 사실 이것도 그냥 컴퓨터다. 이걸로 쓰면 되겠다고 생각해서 사용방법을 익히고 나니 생각이 들었다. 내 컴퓨터도 내가 깨어있을 때 켜 있고 내가 잠을 잘 때는 공지를 보지 않는데 남의 것을 써서 만들어야 할까? 그래서 내 컴퓨터를 사용하기로 마음먹었다. 개인적으로 사용할 것이니 문제가 없을 것이다.

GitAction에 대해 테스트할 때 보던 내용은 아래 글을 참고해서 했었다.

ahnheejong.name/articles/receive-new-room-notification-mails-using-github-action/

 

GitHub Action을 사용해 새로 올라온 전월세 방 목록 받아보기

부동산 앱에 새로 올라오는 방을 매번 직접 체크하는 대신 편하게 받아볼 수 없을까?

ahnheejong.name


 소스 코드가 돌아가는 컴퓨터는 내 컴퓨터로 정했고 나머지는 알림을 보내는 종류를 정하는 것이다. 카카오도 아니고 페이스북도 아닌 메신저를 골라야 했다. 이메일이 있었다. 근본이다. 이메일은 휴대폰에 기본적으로 다 깔려있으며 알림도 뜬다. 파이썬+이메일로 나에게 메일 보내기로 마음먹기로 했다.

 크롤링으로 데이터를 긁어와서 DB에 저장할까란 생각을 했지만 그렇게 관리를 할 데이터들도 아니고 해서 간단하게 JSON형태로 저장하기로 했다.

이메일 보내기

 파이썬으로 메일을 보내는 것은 메일 관련 모듈을 사용하면 된다. 간단한 예제는 아래를 통해서 진행했었다.

pythonstudy.xyz/python/article/508-%EB%A9%94%EC%9D%BC-%EB%B3%B4%EB%82%B4%EA%B8%B0-SMTP

 

예제로 배우는 파이썬 프로그래밍 - 메일 보내기 (SMTP)

메일 보내기 (SMTP Mail) 파이썬에서 이메일을 보내기 위해서는 파이썬에 기본 내장된 smtplib 라는 모듈을 사용한다. SMTP는 Simple Mail Transfer Protocol의 약자로서 메일을 보내는데 사용되는 프로토콜이�

pythonstudy.xyz

그런데? 단순하게 링크만 보낸다면 아니 애초에 공지 헤드라인에 링크가 걸리도록 하려면 무엇을 해야 하나?
HTML를 이용하여 태그로 감싸줘야 한다. a태그라던지 그러면? 이메일 화면도 html로 꾸밀 수 있는 것이 아닌가란 생각이 들었다. 그래서 찾아본다.

이메일을 통한 HTML 보내기 정보 검색

뉴위크나 인프런 소식 등 메일로 보내준다.

텍스트만 들어가는 것이 아니라 버튼도 들어가고 하니 뭔가 다르다고 생각이 들었고 개발자 도구로 확인해보았다.

 

 

 

확인해보니 Table 태그만 사용되어있다. 왜 그럴까? 검색해본다.

이유: 테이블 외 태그는 메일 서비스 회사에서 막아놓는 경우나 각 브라우저마다 기본적인 마진 패딩의 차이가 있으므로 테이블, tr, td만 사용한다.

UI 구성하기

나는 디자인에 대한 감각이 없고, 포토샵도 잘 사용하지 않는다. 친구에게 부탁해도 시안이 없으니 고쳐줄 수도 없는 노릇이다. 그런 나에게 필요한 서비스는? 프로토 타이핑 툴이다. 광고같지만. ㅋㅋ;; 찾아보니 무료인 카카오 오븐이 있어 사용한다.

간단하게 디자인한 후 HTML 코드로 작성한다.

이런 식의 형태로  HTML을 만들고 이를 메일 형태로 보냈다. 보기에도 좋고 나쁘지 않다고 생각이 들었는데 광고를 넣을 수가 없었다. 😃 광고를 넣으면 메일에 (광고)라고 들어가야 하며 구글을 이용한 광고를 넣을 수가 없었다.

 왜 광고를 넣는다는 뚱딴지 소리가 나왔을까? -> 친구에게 말하니 이 서비스를 학교 단위로 늘려나가면 좋을 것 같다고 했다. 그래서 서비스를 하면 나는 돈을 벌고 싶다.
 공부를 해야하지만, 돈은 또 필요하다니 세상마상 모순적인 상황이다. 제일 좋은 것은 자신의 공부가 돈이 되는 경우이고 컴퓨터분야가 그런 것에 강점을 드러낸다고 생각했지만, 남의 데이터로 이렇다 저렇다 하기에는 거시기하다.

 그냥 내가 보기 위해서 이쁘게 만든 파이썬 py 파일 하나만 남았다. 뭐 좋다 이말이다.

내가 쓴 행적을 이렇게만 적어도 되는지 모르겠다. 코드도 넣어야하는지 궁금하기도 한다.
이를 쓴 이유는 내가 고민했던 흔적들을 남기기 위함이기 때문에 일단 이렇게 적은 것인데 도움이 될까..?

다음에 만들 프로그램은 노래 플레이 리스트 공유이다.
사람마다 노래 취향이 다르기 때문에 이를 공유하기 좋게 해주고 싶다.

반응형

+ Recent posts