[안드로이드] 음악 관련 어플 만들기

Updated:

Intro

이번 과제는 관심 있는 주제를 잡아서 멀티 페이지 앱을 만들어보는 과제였습니다. 저는 음악에 관심이 많아서 음악 차트를 순위별로 나열해주는 페이지와, 음악 검색 페이지, 아티스트 정보를 볼 수 있는 페이지를 만들어 보았습니다. 프로젝트에서 구성한 화면의 구조는 아래 그림과 같습니다.

그림1

음악 검색 버튼을 누르면 유튜브로 연결을 해주어서 음악을 유튜브에서 음악을 검색할 수 있도록 해주었습니다. 음악 순위 확인 버튼을 누르면 실시간 멜론 인기차트에서 1위부터 30위까지 크롤링을 해와서 화면에 리사이클러뷰에 띄워줍니다. 또한, 리스트 아이템을 누르면 해당하는 곡의 앨범 정보 페이지로 넘어가게 됩니다. 크롤링해온 문자열에서 앨범아이디를 추출하여 고정되어있는 멜론의 주소에 앨범 아이디 값을 붙여 해당 앨범 정보 페이지로 전환 될 수 있도록 하였습니다. 아티스트 정보 버튼을 누르면 리스트 뷰에 아티스트들을 띄워줍니다. 보고싶은 아티스트를 리스트 아이템을 클릭하면 해당하는 아티스트의 상세 정보 페이지로 전환됩니다. 메인을 제외한 모든 페이지는 뒤로가기 버튼으로 되돌아 갈 수 있습니다.

메인 페이지

먼저 메인 페이지의 레이아웃은 다음과 같이 xml을 작성하였습니다.

그림2

ConstraintLayout에 Jiwon Music이라는 textView와 음악 검색, 음악 순위, 아티스트 정보 버튼 세개를 배치하여 주었습니다. 배경화면 색은 따로 res>drawable 디렉토리에 gradient_backgroun.xml을 정의해주어 제가 마음에 드는 색상을 그라데이션으로 나오게하는 배경화면을 정의해 주었습니다. xml에서 적용할 때는 아래와 같이 적용하여 주었습니다. 모든 페이지의 배경화면 색을 gradient_background 값으로 지정하였습니다.

android:background="@drawable/gradient_background"

그림3

아래 사진은 어플을 실행 시켰을때의 메인 화면 입니다. 배경색을 정의 해주었을 뿐만 아니라 글씨체도 새로 정의하여 변경하여 주었습니다. 화면을 배경화면과 글씨체 모두 잘 적용된 모습을 확인할 수 있습니다.

그림4

각 버튼들은 버튼 Listener를 달아주고 onClick()메소드에 연결시켜주어 이벤트 처리를 하였습니다

그림5

음악 순위 페이지

음악 순위 버튼을 누르면 전환되는 페이지 입니다. 실행 시키기 전에는 아무것도 없어 보이지만 실행을 시키면 아이템 리스트들이 출력됩니다. 그 이유는 recyclerView를 사용하였기 때문입니다.

그림6

리사이클러뷰(RecyclerView)는 많은 수의 데이터 집합을, 제한된 영역 내에서 유연하게 표시할 수 있도록 만들어주는 위젯입니다. 사용자가 관리하는 수 많은 데이터 집합을 개별 아이템 단위로 구성하여 화면에 출력하는 뷰그룹이며, 한 화면에 표시되기 힘든 많은 수의 데이터를 스크롤 가능한 리스트로 표시해줍니다.

리스트뷰(ListView)를 사용할 경우, 리스트 항목이 갱신될 때마다 매번 아이템 뷰를 새로 구성해햐한다는 문제점이 있습니다. 이는 많은 데이터 집합을 표시하는 경우 성능 저하를 일으킬 수 있습니다. 이런 리스트뷰의 단점을 보완하기 위해 리사이클러뷰는 아이템을 표시하기 위해 생성한 뷰를 재활용 합니다. 그리고 이를 위해 기본적으로 뷰홀더 패턴을 사용하도록 만들어 놓았습니다.

그림7

위와 같이 데이터를 처리하기 위해서 ChartActivity와 ChartDTO 클래스와 RecyclerAdapter 클래스를 정의하여 주었습니다.

가장 먼저 RecyclerAdapter의 역할은 리사이클러뷰에 표시될 아이템 뷰를 생성합니다. 사용자 데이터 리스트로부터 아이템 뷰를 만드는 것이 어댑터가 하는 역할 이빈다. 이 클래스에서 출력될 뷰의 요소들이 설정됩니다. 이곳에서 뷰홀더(View Holder)가 정의 됩니다. 뷰홀더는 화면에 표시될 아이템 뷰를 저장하는 개체입니다. 미리 정의해 놓은 데이터들이 뷰홀더의 아이템 뷰에 바인딩(Binding)됩니다.

그림8

뷰를 생성할 때, onClick메소드를 정의하여 각 아이템들의 클릭 이벤트를 처리하였습니다. 아이템들을 누르면 크롤링해 왔던 href 속성 값에서 클릭 한 아이템의 앨범 아이디 값을 추출하여 고정되어 있는 앨범 디테일 주소 뒤에 문자열을 덧붙여 줍니다.

그림9

그렇게 완성된 url을 intent에 넣어주면 아이템이 클릭 될 경우 detil.html + ablumId = … 주소로 디테일 페이지로 이동하게 됩니다.

그림10

그림11

ChartActivity에서는 멜론 주소 를 통해 현재 실시간 차트를 1위부터 30위까지 크롤링 해 옵니다. 이때 Jsoup이라는 자바로 만들어진 HTML 파서(Parser)를 사용하여 URL로 하여 HTML을 파싱했습니다. Jsoup을 이용하여 곂치고 쌓여져있던 태크들 중에서 필요한 태그들의 값을 가져왔습니다. 그 정보들은 각각 ArrayList에 저장 됩니다. 아이템을 클릭 할 경우, 해당 앨범의 아이디 값만을 추출하여서 기존의 주소에 붙여주었어야 했습니다. indexOf와 substring과 같은 문자열 처리 메소드를 사용하여 앨범 아이디 값을 뽑아낼 수 있었습니다.

그림12

Log.d로 출력한 앨범 아이디 값과 URL의 앨범 아이디 값이 일치하는 것을 확인 할 수 있습니다.

그림13

리스트 아이템들의 레이아웃으로는 CardView를 사용하였습니다. 해당 레이아웃 안에 순위가 몇위인와 앨범 사진, 노래 제목, 가수 이름이 나오도록 TextView를 넣어 주었습니다.

아래는 실행 했을 경우의 화면입니다. 리스트 아이템을 선택했을 경우 그에 해당하는 앨범 상세페이지로 이동하는 것을 확인 할 수 있습니다.

그림14

아티스트 정보 페이지

다음으로는 아티스트 정보를 눌렀을 경우 입니다. 해당 페이지의 레이아웃은 ListView를 사용하였습니다. Custom ListView를 만들기 위해 activity_artistinfo.xml에 listView를 추가하였습니다. 해당 위치가 ListView가 표시될 위치입니다. ListView 아이템에 대한 Layout을 구성하기 위해 artist_item.xml에 Layout 리소스를 작성하였습니다.

그림15

그림16

그 후, ArtistDTO 클래스에서 아티스트 아이템에 대한 클래스를 정의하였습니다.

그림17

해당 클래스는 Parcelable을 implements하였습니다. 그 이유는 ArtistinfoActivity에서 DetailActivity로 전환 될 때, ArtistDTO를 인텐트에 같이 넘겨 주었습니다.

그림18

그런데 ArtistDTO 객체에서 사진에 해당하는 객체인 Drawable 객체로 인해 오류가 발생하였습니다. Parcelable을 implements한 후, DetailActivity에서 Bundle로 인텐트를 받도록하여 오류를 해결하였습니다.

그림19

Parcelable는 사용자에 의해 정의되는 자료형을 알 수 없는 객체를 생성 후 액티비티 간에 전달하고자 할 때 사용합니다. Bundle로 넘겨 받은 아티스트의 정보가 담겨있는 item객체의 속성 값들을 뷰 속성들에게 설정 하여 주어 선택한 아티스트의 정보들이 디테일 화면에서 출력될 수 있도록 하였습니다.

그림20

결과

  • 메인 화면

그림21


  • 음악검색 버튼을 누를 경우 유튜브 페이지로 전환

그림22


  • 음악 순위 버튼을 누를 경우 멜론에서 크롤링한 실시간 차트 출력

그림23


  • 리스트 아이템을 선택했을 경우, 해당하는 앨범 상세페이지로 전환

그림25

그림26


  • 아티스트 정보를 선택한 경우, 아티스트 리스트가 출력 / 아티스트를 선택하면 해당하는 아티스트에 대한 정보 출력

그림27

참고

전체 코드는 AndroidProject_myMusicApp에서 확인할 수 있습니다.

Leave a comment