2023년 12월 15일 금요일

Android Tv App - Basic

Android Tv App - Basic

Android TV 앱 개발 E-BOOK (Basic)

enter image description here

ⓒ 2021. Sugoi Group All rights reserved.
ⓒ 2021. provided by DX-NINJA, DX-JAPAN.

앱 개발 및 기타문의 : : cg99132@gmail.com
일본에서 프로그래머 취업하기 : (카카오톡 오픈 토크)

E-BOOK PDF 버젼 보기

0. 준비단계

지루하고 일방적인 방송만 송출하는 고가(?)의 TV화면이 Android TV를 설치한 순간 SMART한 대형 타블렛으로 만들어 줍니다.
Android TV는 지금까지는 일반 앱에 비해서는 인기가 없었지만, 최근 Netflix, Amazone Prime Video, Hulu 등 OTT업체들의 인기에 힘입어 다시 주목받고 있는 중입니다.

알다시피 Android TV (Google TV)는 SMART TV전용 운영체제입니다. 단,TV라고는 해도 내부는 Android OS 가 탑재되어 있으니 덩치만 큰 안드로이드 기기 라고 생각해도 됩니다.

Android TV 앱제작은 일반 앱제작과 거의 차이가 없지만 장치가 TV인 만큼 UX/UI는 조금 다르게 생각할 필요가 있습니다. 보통 일반사람들은 TV 화면에 직접터치하지 않고 리모콘이라는 것을 사용하는 만큼 그에 따른 포커스커서의 이동에도 매우(강조함!) 신경써야 합니다.

다행히 구글은 초기때부터 Android TV용 앱 개발을 쉽게 하라고 Leanback Library 를 제공하고 있습니다.
Google의 공식 문서에 따르면 Android TV와 Leanback은 모두 사용자가 이상적인 3미터 TV 시청 경험(10피트 경험)을 가질 수 있도록 하기 위해 태어났다고 합니다.
개발자들은 TV용 앱개발시에 Leanback Library를 이용하여 좀더 빠르고 쉽게 그럴듯한 TV용 앱을 만들수 있습니다. Leanback에 기대는 방법은 예제를 통해 천천히 알아보도록 합시다.

기존의 안드로이드 앱 개발과는 약간 다른 맛이지만 대형화면에 시원시원하게 보이는 TV앱 개발의 색다른 맛에 빠져봅시다.

0.1 Kotlin 언어

왜 Kotin? 라고 질문하는 사람있을까요? Java도 훌륭하지만 Kotlin으로 개발하면 반복되고 지루한 보일러코딩을 줄일수 있습니다.
아직 Kotlin에 대해 한번도 안 다뤄봤다면 이번기회에 Kotlin을 배워보는것도 추천합니다.
수동기어 자동차를 타다가 최신식 자동기어(오토) 자동차를 탄 기분일겁니다.

Kotlin언어에 대한 자세한 설명은 https://kotlinlang.org/ 에서 천천히 읽어 보시길 바랍니다.

0.2 Android Studio 다운로드

Android 앱을 개발한다면 너무나 당연한 개발 툴이죠. 간단한 계산기 앱하나 개발하려고 해도 관련라이브러리설정, 에뮬레이터설정, 환경설정, 여러가지 세팅, 폴더구조의 일치 등 수동으로 하기에는 혼이 나갈 정도로 복잡한데 Android Studio 에서는 그걸 전부 편하게 할 수있도록 도와 줍니다. (Android초창기부터 개발한 개발자들은 Eclipse라는 에디터에서 환경설정하다가 한번쯤은 키보드 내리친 적이 있죠)

공식 홈페이지에서 무료로 다운받을수 있습니다.
https://developer.android.com/studio

0.3 Android OS가 탑재된 SMART TV 또는 Fire TV등 (없어도 그만)

개발할때는 자신의 PC에서 에뮬레이터를 가동해서 개발할수가 있지만, 실제 화면에서 어떻게 보일지 잘 동작할지 테스트도 해봐야 겠죠?

1. Android TV 둘러보기

자. 그럼 덩치만 큰 안드로이드 기기는 어떻게 동작하는지 둘러봅시다.
Smart TV장비가 있으면 좋겠지만, 없어도 에뮬레이터를 실행해서 구동환경을 시험해 볼수 있으니 둘러보는데는 문제없습니다.

1.1 에뮬레이터에서 구동하기

안드로이드 스튜디오를 실행해서 Tools ->Device Manager를 선택합니다.
enter image description here
Virtual->Create Device화면에서 Category ->TV를 선택합니다.
enter image description here
사이즈는 적당히 선택하면됩니다만 에뮬레이터가 그렇게 빠르지 않은편이니 작은 화면을 선택해봅니다.
다음화면으로 가면 안드로이드TVOS를 선택하라는 화면이 나옵니다.
적당한걸 받아도 좋지만, 기왕이면 최신버젼의 OS를 다운받아봅시다.
enter image description here
다음화면에서는 AVD Name 등 몇가지 옵션이 나오는데 지금은 그냥 Finish해서 완료합니다.
enter image description here
디바이스 목록에 방금 추가한 것이 리스트에 보입니다. > 버튼을 선택하여 실행하면 에뮬레이터 TVOS가 기동됩니다.
enter image description here

1.2 DPAD로 포커스 이동해보기

자 이제 화면의 포커스를 이동해서 앱들을 실행해보고 설정을 변경해봅시다.
점3개 아이콘을 클릭하면 DPAD(Direction PAD)라는 게 보입니다.
enter image description here

네. TV는 기본적으로 리모콘을 사용하기 때문에 에뮬레이터도 DPAD를 이용하여 화면의 포커스를 이동한답니다.
DPAD의 ↑↓→←버튼을 눌러서 이동하고, 선택버튼으로 앱을 실행하거나, 동영상을 플레이 등을 할수 있습니다.
터치패드처럼 세련된 방식이 아니라 처음에는 조금 갑갑하지만 TV환경에서는 익숙해져야한 합니다.
우리도 이제 이 DPAD의 키에 제대로 반응해야하는 TV앱을 제작할 겁니다.
enter image description here

1.3 개발자 모드로 만들기

기왕 둘러보는 김에, 개발을 할때 디버깅등을 쉽게 하기위해서 개발자모드를 On으로 해야합니다.
안드로이드폰에서 개발자모드를 몰래(?) 여는 방법하고 동일합니다.
DPAD의 톱니바퀴(Setting)을 클릭해서
enter image description here
Device Preference->About->Android TV OS Build라는 항목에 포커스를 놓고서는 6번 선택버튼을 연타하면 개발자모드가 열렸다고 메시지가나옵니다.
enter image description here

enter image description here
이제 개발자만 들어갈수 있다는 비밀의 방(?) 인 Device Preference->Developer Options가 새로 생겼답니다.
enter image description here

enter image description here
개발자모드와 개발시의 디버깅은 나중에 개발예제에서 하나씩 설명합니다.

2. TV APP 디자인

TV의 가장 직관적인 느낌은 큰 화면이지만 근본적으로 다른 휴대폰의 확대 버전이라고 볼 수는 없습니다.

TV UI를 디자인할 때 2미터, 3미터 거리에서 디자인이 보일지 고려하는 것이 필요하며, TV와 휴대폰의 시청 거리가 다릅니다.

작은 화면에 조밀조밀하게 배치하는 휴대폰 앱 디자인과는 근본적으로 다르며, 디자인할 때 큰 블록, 여백, 스크롤링, 포커스 효과 등에 주의하고 차이점을 이해해야 합니다.

2.1 OverScan 에 대한 이해.

오버스캔이란 무엇입니까? 공식 설명은 다음과 같습니다.

TV 기술이 발전하는 동안 overscan은 원래 대부분의 TV가 안정적으로 표시할 수 있는 안전 영역 외부의 TV 콘텐츠 영역을 설명했습니다. 오늘날의 일부 HDTV 평면 화면에서도 해당 영역 밖의 영역은 표시되지 않을 수 있습니다.

전체 디스플레이 인터페이스는 전체 외부 직사각형 상자이고 가시 영역은 내부 직사각형 상자이므로 테두리 가까이에 콘텐츠를 배치하면 일부 TV에서 전체 콘텐츠가 완전히 표시되지 않을 수 있습니다.

2.2 OverScan 을 고려한 UI 조정

공식 문서에도 솔루션이 나와 있습니다.

TV 화면 디자인에 5% 여백을 만들어 TV가 올바르게 표시되지 않을 수 있는 오버스캔 영역을 고려합니다. 1920 x 1080 화면에서 이 여백은 위쪽 및 아래쪽 가장자리에서 최소 27픽셀(위아래), 최소 48픽셀(좌우)이어야 합니다.

위의 의미는 인터페이스를 디자인할 때 주변의 오버스캔 거리를 비워두는 것을 의미합니다.1920*1080을 예로 들면 상하가 27px, 좌우가 48px이므로 표시되는 내용이 안전하게 표시됩니다.

단점: 디자인의 콘텐츠가 테두리에 가까워야 하는 경우, 예를 들어 하단에 탐색 모음이 있어 표시 및 숨길 수 있는 경우 디자인이 테두리에 가까워야 합니다.

enter image description here

2.3 화면 배치

Android TV의 첫화면에는 앱목록, 추천영상, 설정, 검색 등이 제공됩니다.
앱은 사용빈도에 따라서 최신순으로 정렬됩니다.
화면은 가로방향입니다. 보통의 TV화면을 생각하면 당연합니다.
각 요소들은 위/아래/좌우가 확실히 구분되는 방식으로 배치해야 좋습니다.
일단 앱처럼 너무 복잡하게 배치하면 사용자 인터페이스가 매우 안좋게 될수도 있습니다.
아래와 같이 일반앱처럼 디자인 하지 마세요.
enter image description here

TV조작에 알맞게 디자인 하세요.
enter image description here

2.4 색상배치

TV 의 액정은 밝기(휘도) 가 굉장히 높아서 사용자가 지속해서 같은 밝은 빛을 보았을때 쉽게 피로감을 느끼게 됩니다.
따라서 UX의 전체적인 톤은 너무 밝지 않게 하는것이 좋습니다.
예를들어 하얀색배경의 경우 밝은회색(#EEEEEE)정도로 해주는 것이 좋습니다.

2.5 탐색, 포커스

TV기기는 DPAD라는 리모콘을 이용합니다. DPAD는 좌우상하,선택 버튼으로 구성되어 있기 때문에, TV용 앱을 개발할때도 이러한 특성맞게 포커스의 이동이 자연스럽게 되도록 구현해야합니다.
그림출처: https://developer.android.com/design/tv
그림출처: https://developer.android.com/design/tv

3. Android Studio에서 TV앱 프로젝트 만들기

자, 이제 대충 TV앱이 어떤 녀석인지 느낌상 알게되었으니, Android studio에서 샘플프로젝트를 만들어서 Android TV안에 우리앱을 넣어봅시다.

3.1 Blank TV App

Android Studio에는 안드로이드 앱을 만들기 위한 기본 템플릿(일반앱, TV앱, 시계앱, 자동차용앱)을 제공하기 때문에 우리는 그냥 선택만 해서 생성하면 TV 앱의 골격이되는 형태의 빈 앱을 만들수 있습니다.

File->New Project->Android TV ->Blank Activity 를 선택하고 Next합니다.
enter image description here

프로젝트이름, 패키지명,저장위치 등은 대충 지정하거나 그냥 그대로 두고, Language 가 Kotlin인지 확인하고 Finish합니다.

프로젝트 생성은 쉽게 했지만, Android Studio 가 Gradle이라는 프로젝트의 설정값에 써있는 안드로이드와 TV앱개발 관련라이브러리들을 꽤 오랜시간 열심히 읽어 들입니다.
기다림이 끝나고 MainActivity.kt, activity_main,.xml두개의 파일이 에디터에서 자동으로 열리면서 화면에 무언가를 넣어주기를 간절히 바라고 있습니다.
비어있는거 같지만, 샘플앱에는 이미 많은 파일들이 구성되어 있기 때문에 그냥 그대로 실행만 해도 됩니다.
enter image description here

3.2 TV App 설치 & 실행

이제 프로젝트를 생성했으니 당장 실행해서 Android TV화면에 설치해 보고 실행해 봅시다.
안드로이드 스튜디오에서는 녹색(>)을 눌러 실행하면 자동으로 현재 프로젝트를 빌드->앱설치->실행 까지 해줍니다.
enter image description here
아무것도 안했는데, 카테고리며, 썸네일이미지,리스트등 완벽한 형태의 앱이 이미 만들어 져서 실행되고 있습니다.
enter image description here
TV앱은 일반앱에 비해 UX 가 까다로운 편이라 구글에서는 아예 완벽한 샘플을 프로젝트기본형태로 제공해서 초보자들은 그걸가지고 수정해서 앱을 만들기를 바랬던것같습니다.
DPAD의 홈버튼을 누르고 상단멘유의 Apps를 선택해보면 우리가 방금 설치한 녹색의 아이콘이 보입니다. ( Android TV 버젼에 따라 안보일수도 있습니다. TV홈화면에서 [+} 버튼을 클릭해서 홈화면에 추가해도 됩니다)
사용자들도 구글 스토어에서 설치한 우리앱을 Apps메뉴에서 선택해서 실행하게 될것입니다.

4. Leanback 라이브러리

구글은 안드로이드 TV 개발자들이 앱사용자들에게 일관적이면서 좀더 나은 UX 를 경험할수있도록 Leanback라이브러리를 제공하고 있습니다.
물론, Leanback을 사용하지 않고도 TV용앱을 개발 할수도있습니다. 다만, Leanback을 사용하면 좀더 편하고 빠르게 TV다운 인터페이스를 구현할수 있기 때문에 Leanback라이브러리 사용을 권장합니다.

Leanback라이브러리에는 TV앱 화면구성을 위한 다양한 Fragment가 정의되어있고, 이들 요소들이 서로 상호작용할수록 미리 설계되어있습니다.
개발자는 이들 Fragment를 사용하거나 확장하여 자신만의 화면의 구성하고 좀더 멋진 인터페이스를 만들 수도 있습니다.

4.1 Fragment & SupportFragment

Leanback에서는 TV화면앱의 구성을 쉽게 하도록 도와주기 위해서 미리 정의된 XXXSupportFragment들을 이용합니다.
enter image description here
예를들어

  • BrowseSupportFragment
  • VerticalGridSupportFragment
  • DetailsSupportFragment
  • RowsSupportFragment
  • ErrorSupportFragment
  • HeaderSupportFragment
  • OnboardingSupportFragment
  • PlaybackSupportFragment
  • SearchSupportFragment
    등이 있습니다.

4.2 Widget

TV앱은 주로 플레이할 영상아이템 목록을 보여주고 선택된 아이템에 해당하는 상세정보를 보여준다음 플레이 하는 기능이 대부분입니다.
이런 구성들을 쉽게 하기위해서 Leanback 에서는

  • Adapter
  • Presenter
  • PresenterSElector
  • Model
  • View
  • Util
    같은 위젯들을 제공합니다.

5. 샘플 프로젝트 소스 훓어보기

자. 그럼 샘플 프로젝트에서는 Leanback라이브러리를 사용해서 어떻게 샘플앱처럼 화면을 구성하고 동작시켰는지 봅시다.

5.1 build.gradle에서 leanbak 라이브러리 정의 확인

gradle이라는 애플리케이션빌드 도구를 이용하면 사용하고자 하는 라이브러리의 이름만 설정화일에 입력만해도 자동으로 관련 라이브러리가 다운로드 되어집니다.
샘플프로젝트에서도 build.gradle(Module:프로젝트이름.app)에 아래와 같이 추가되어 있습니다.

implementation 'androidx.leanback:leanback:1.0.0'

네. leanback을 사용하겠다는 겁니다.

5.2 AndroidManifest.xml파일에서 LEANBACK-LAUNCHER확인

Android TV용 앱은 manifest파일에 TV용앱이라는 것을 식별할수 있도록 Main이 되는 액티비티에 아래와 같이 카테고리를 지정해야 합니다.

...
<category  android:name="android.intent.category.LEANBACK_LAUNCHER"  />
...

그리고 leanback 라이브러리를 지원하는 Android TVOS 에서만 실행된다면 아래와 같이 leanback사용자인터페이스를 사용(true)한다고 선언합니다.

<uses-feature  
  android:name="android.software.leanback"  
  android:required="true" />

터치스크린 장치가 아니므로 touchscreen 관련 항목도 false로 선언합니다.

<uses-feature  
  android:name="android.hardware.touchscreen"  
  android:required="false" />

이렇게 설정이 된후에야 Android TV OS가 leanback의 사용자인터페이스를 사용한 TV용 앱이라는 것을 알수 있게됩니다.

추가로, TV화면에 우리의 앱의 배너이미지를 추가하여 Drawble폴더에서 각 현지화에 맞는 아이콘을 제공할수도 있습니다.

 <application ... 
     android:banner="@drawable/banner"  > 
     ... 
 </application>

자. AndroidManifest.xml 을 보면 위에서 말한게 모두 선언되어 있죠? 우리만들 앱도 위의 항목들을 기본적으로 선언해야 합니다.

5.3 MainFragmen는 BrowseSupportFragment를 계승받아서 구현

enter image description here
앱의 실행 activity인 MainActivity에서 MainFragment로 화면구성하는것을 알수있습니다.
Mainfragment는 Leanback의 BrowseSupportFragment를 계승했기 때문에 헤더,카테고리목록, 하위아이템목록 으로 구성되어 있는 Browse 화면구성을 할수 있습니다.
따라서, MainFragment에서는 별도의 레이아웃없이 카테고리 타이틀목록과 아이템만 데이터만 지정하고도 카드뷰아이템으로 구성된 샘플같은 화면이 구성이 될수 있는 것입니다.

// BrowseSupportFragment를 계승하여 부모의 모든 기능을 이용
class MainFragment : BrowseSupportFragment() {
    // UI 구성을 합니다.
    private fun setupUIElements() {
        // 테스트로 헤더 타이틀 글씨를 바꾸어 봅시다.
        title = getString(R.string.browse_title)
        // 헤더 타이틀이 필요하다고 선언
        headersState = BrowseSupportFragment.HEADERS_ENABLED
        // brandColor , searchAffordanceColor 는 BrowseSupportFragment에 정의되어 있습니다.
        ...
    }

    // 카테고리와 하위 아이템 데이터를 Presernter를 통해 adaptor 에 설정합니다.
	private fun loadRows() {  
	    val list = MovieList.list  
	  
	  // ListRowPresernter는 Leanback에서제공하는 간단한 세로목록용 프레젠터(데이터의 화면표시를 도와주는) 입니다. 프레젠터를 애덥터에 연결하여 애덥터가 프레젠터를 통해 화면에서 프레젠터가 의도한 대로 화면에 보이도록 합니다.
	    val rowsAdapter = ArrayObjectAdapter(ListRowPresenter())  
	    // CardPresenter는 데이터를 카드형태로 표시되도록 도와주는 프레젠터입니다.
	    val cardPresenter = CardPresenter()  

	    for (i in 0 until NUM_ROWS) {  
	        if (i != 0) {  
	            // 한정된 하위 아이템리스트 데이터들을 각 카테고리별로 다른순서로 보이도록 속이기 위해서 단순히 섞었습니다. 
	            Collections.shuffle(list)  
	        }  
	        // 카드 프레젠터를 애덥터에 추가합니다. 
	        val listRowAdapter = ArrayObjectAdapter(cardPresenter)  
	        // 카드 애덥터의 각 요소에 하위 아이템리스트를 추가합니다.
	        for (j in 0 until NUM_COLS) {  
	            listRowAdapter.add(list[j % 5])  
	        }  
	        // Header즉 샘플에서는 각 카테고리메뉴아이템을 지정합니다.
	        val header = HeaderItem(i.toLong(), MovieList.MOVIE_CATEGORY[i])  
	        // listrowPresernter가 지정된 rowsAdapter에 헤드와  하위아이템 리스트에대한 정보를 담은 listRowAdapter를 추가하여 타이틀과 하위데이터집합을 논리적으로 연결해 놓습니다.
	        rowsAdapter.add(ListRow(header, listRowAdapter))  
	    }  
	    // 샘플에서는 카테고리 최하위에 PREFERENCES 타이틀항목을 추가합니다.
	    val gridHeader = HeaderItem(NUM_ROWS.toLong(), "PREFERENCES")  
	  
	    // GridItemPresenter는 Presenter를 계승하여 사용자정의형태로 수정한 것으로 샘플에서는 프레젠터를 이용하여 화면 구성을 맘대로 바꿀수 있다는 것을 보여 주기 위한것 입니다.
	    val mGridPresenter = GridItemPresenter()  
	    // gridRowAdapter에 GridItemPresenter를 지정하여 격자형태로 아이템들이 표시되도록합니다.
	    val gridRowAdapter = ArrayObjectAdapter(mGridPresenter)  
	    // 각각 GridVIew, Error Fragment, Personal setting 아이템을 grridRowAdapter에 추가합니다.    gridRowAdapter.add(resources.getString(R.string.grid_view))  
	    gridRowAdapter.add(getString(R.string.error_fragment))  
	    gridRowAdapter.add(resources.getString(R.string.personal_settings))  
	    // 앞서 선언한 ListRowPresernter으로 구성된 rowsAdapter에 방금추가한 PREFERENCES 타이틀과 하위3개의 아이템을 추가합니다.
	    rowsAdapter.add(ListRow(gridHeader, gridRowAdapter))  
	    // adapter는 BrowseSupportFragment에서 관리하는 adapter 로서 Presenterselector를 통해서 각각 타이틀과 아이템목록영역에 해당 항목들을 표시합니다.
	    adapter = rowsAdapter  
	}  
  
    private fun setupEventListeners() {
        // 하위아이템이 클릭되면 해당 자료의 액티비티화면으로 이동합니다.  
        onItemViewClickedListener = ItemViewClickedListener()  
        // 하위아이템이 선택되면 배경이미지를 변경합니다.
        onItemViewSelectedListener = ItemViewSelectedListener()
    }
  
    // Presenter를 직접 계승하여 GridItemPresenter처럼 모양을 다양하게 구성할수도 있습니다.
    private inner class GridItemPresenter : Presenter() {

    }
}

자. 이제 대충 감이 오나요?
요약하자면,
화면의 큰 구성요소들은 Leanback에서 제공 XXXSupportFragment를 계승받고, 각각의 요소들은 XXXPresenter 를 이용하거나, 또는 원하는 형태로 Presenter를 만들어 Adapter에 연결한다음 SupportFragment에서 관리하는 Adapter에 연결하면 나머지는 Leanback에서 알아서 합니다.

5.4 DetailFragmen는 DetailsSupportFragment를 계승받아서 구현

enter image description here
영상아이템을 선택했을떄 보이는 DetailActivity화면 구성을 분석해 봅시다.DetailAcivity는 DetailFragment를 불러내는 것뿐이니 DetailFragment를 봅시다.
DetailFragment도 Leanback의 DetailSupportFragment를 계승받아서 구성하고 있습니다.

class VideoDetailsFragment : DetailsSupportFragment() {
    // ClassPresenterSelector는 주어진 class이름을 기반으로 아답터에서 Presenter를 선택할수있도록 합니다. Presenter를 선택한다는 것은 데이터에 따라 화면 출력시 다른 모양으로 출력할수 있도록 가능하다는 것을 말합니다. 샘플 예제에서는 Leanback에서 제공하는 상세보기 화면 DetailsOverviewRow와 관련 항목표시용 ListRow를 ClassPresenterSelector에 추가하여 화면 상단에서는 상세보기내용이, 하단에는 관련 비디오 목록이 보이도록 구성되어있습니다. 
    private lateinit var mPresenterSelector: ClassPresenterSelector
      
  
    override fun onCreate(savedInstanceState: Bundle?) {
        ...  
		if (mSelectedMovie != null) {  
		    // Leanback의 ClassPresenterSelector를 사용합니다.
		    mPresenterSelector = ClassPresenterSelector()  
		    // mAdapter에 PresenterSelector를 추가한다는 의미는  하나의 애덥터에 다양한 출력형식의 Presenter가 존재하니까, 데이터에 따라서 Presenter를 선택하여 화면에 적절히 표시하겠다는 의미입니.
		    mAdapter = ArrayObjectAdapter(mPresenterSelector)  
		    // 아래 참조.
		    setupDetailsOverviewRow()  
		    setupDetailsOverviewRowPresenter()  
		    setupRelatedMovieListRow()  	
		    // 화면출력용 Adapter, presenterSelector, presenter, row 지정이 끝나면 화면구성을 알아서 모아서 출력하는 DetailSupportFragment의 adapter에 현재 구성한 mAdapter를 지정합니다.   
		    adapter = mAdapter	    
		    ...
    }  
  
    private fun setupDetailsOverviewRow() {
       // Leanback의 DetailOverviewRow에 Movie데이터를 넣습니다. 
        val row = DetailsOverviewRow(mSelectedMovie)
        ...
        val actionAdapter = ArrayObjectAdapter()  
        ...    
		// DetailsOverviewRow의 아답터를 지정하고, 전체구성의 mAdapter에 추가합니다. 지금은 아덥타만 지정했을뿐 화명에 데이터를 어떤형식으로 출력할 Presenter는 아직 설정되지 않은 상태입니다.
        row.actionsAdapter = actionAdapter
        mAdapter.add(row)
    }
    
    private fun setupDetailsOverviewRowPresenter() {
        // Set detail background.
        // AbstractDetailsDescriptionPresenter를 계승하여 DetailsDescriptionPresenter를 만든후에 전체배경화면을 지원하는 FullWidthDetailsOverviewRowPresenter로 한번더 감쌌습니다. 결국 Presenter입니다.
        val detailsPresenter = FullWidthDetailsOverviewRowPresenter(DetailsDescriptionPresenter())
       

        // Hook up transition element.
        // 목록화면에서 아이템을 클릭했을때, 해당 아이템의 위치에서 상세보기화면의 아이템사진위치까지 부드럽게 이동하는 것을 표현하기 위해서, FullWidthDetailsOverviewSharedElementHelper를 이용했습니다.SHARED_ELEMENT_NAME는 MainFragment에서 Bundle(ActivityOptionsCompat.makeSceneTransitionAnimation(...,DetailsActivity.SHARED_ELEMENT_NAME ))형태로 넘어온데이터이기 때문에 상세보기화면으로 이동과 동시에 번들로 넘어온 애니메이션을 실행할수 있는겁니다.
        
        val sharedElementHelper = FullWidthDetailsOverviewSharedElementHelper()
        sharedElementHelper.setSharedElementEnterTransition(
            activity, DetailsActivity.SHARED_ELEMENT_NAME
        
        ...
        // 이제 PresenterSelector에게 DetailsOverviewRow클래스의 경우 detailsPresenter를 이용해서 화면 출력하라고 지정합니다.
		mPresenterSelector.addClassPresenter(DetailsOverviewRow::class.java, detailsPresenter)
    }
    
    private fun setupRelatedMovieListRow() {
        // 관련영상 리스트출력을 위해 PresenterSelector에게 ListRow클래스의 경우 ListRowPresenter를 이용해서 화면 출력하라고 지정합니다.
        mPresenterSelector.addClassPresenter(ListRow::class.java, ListRowPresenter())
    }
}

5.5 Leanback을 이용한 TV 화면 구성에 대한 정리

MainFragment, DetailFragment의 예제에서 보았다시피, XXXSupportFragment를 계승하여 그럴듯한 TV 화면 구성을 쉽게 할수 있다는 것을 알수 있습니다.
XXXSupportFragment에는 반드시 1개의 adapter가 존재하여 SupportFragment 가 사용자가 구성한 Row 아이템을 Presenter를 통해 화면에 표시 하고 있습니다.

6. Leanback Showcase 로 더많은 예제보기

SupportFragment와 Widget들을 이용하여 어떤 화면을 구성할수 있는지, 어떤 인터페이스까지 가능한지 아직은 궁금할것 입니다.
개발자들의 그런 궁금증을 해결해 주기 위해서 Leanback Showcase라는 것을 제공하여 개발자들이 TV앱을 어떻게 구성가능한지를 보여줍니다.

앞서 Android Studio의 TV 샘플앱에서 XXXSupportFragment, XXXAdapter, Presenter, XXXRow 들이 어떤 관계를 가지고 화면을 구성하는 간단히 알아보았기 때문에 ShowCase의 다른 예제들도 천천히 분석해서 자신만의 다양한 화면을 구성할수 있으리라 생각됩니다.
enter image description here

6.1 Github 에서 leanbackShowCase 를 다운받기

GitHub에는 세계여러개발자, 개발회사들이 자신들의 프로젝트를 공개하여 서로 공유하고 개선해 나갈수 있도록 하고 있습니다.
구글도 Leanback을 이용하여 TV앱을 개발하는 개발자들을 위해서 Leanback 라이브러리를 활용한 ShowCase샘플앱을 제공하고 있습니다.

자신의 PC의 적당한 디렉토리 에서 git 명령어로

git clone  https://github.com/android/tv-samples 

을 치면 leanback Showcase프로젝트가 전부 현재 폴더에 복제되어 집니다.

6.2 Android Studio에서 LeanbackShowcase 프로젝트열기

안드로이드 스튜디오의 File->Open 을 선택한다음 다운받은 폴더의 하위의 leanbackShowcase 폴더를 선택하고 Open합니다.

프로젝트가 불려지면서 관련라이브러리들이 자동으로 다운로드 되며 실행할 준비가 됩니다.
app -> > 를 선택해서 실행합니다.

자 이제 ShowCase의 다양한 화면처럼 우리 앱도 구성할수 있습니다.

부록

Android TV 관련 공식 자료

관련용어

SMART TV앱 개발시에 사용하는 여러가지 용어들이 있습니다. 간단히 이해하고 넘어가는게 좋습니다.

UI ( User Interface )

Android TV 인터페이스 개발은 기존의 휴대 전화 단말기 개발과 다릅니다. TV 단말기의 상호 작용은 주로 사용자의 원격 제어 조작에 의해 완료되므로 TV에 대한 버튼 처리 및 초점이 특히 중요합니다.
둘째, 출력 표시 매체 TV 터미널은 주로 TV 디스플레이입니다.
다른 TV는 다른 입력 디스플레이 해상도를 지원할 수 있으므로 해상도 적응도 TV 인터페이스 개발에서 고려해야 할 포인트입니다. 또한 TV 인터페이스 디자인도 작은 화면 디스플레이와 다릅니다.
큰 화면 디스플레이로 인해 UI 디자인은 보다 평면적이고 편리해야 합니다.

IPTV

인터넷 프로토콜 TV, 즉 인터넷을 이용하여 방송 TV를 볼 수 있는 것을 말합니다.

OTT(Over The Top)

기존의 영상제공 서비스가 세톱박스(통신사가 제공하는 수신기)라는 특정장치를 이용해서 영상서비스를 제공했던 것이라면 OTT 는 빠른 인터넷통신을 이용하여 셋톱박스 없이도 인터넷만 되면 어디서든 영상서비스를 제공하는 것을 말합니다.
IPTV시장이 활성화 되면서 OTT서비스를 제공하는 업체들이 우후죽순 생기기 시작했습니다. OTT는 주로 동영상, 스트리밍 미디어 컨텐츠들을 제공하는 것을 말합니다.

PIP(Picture-in-Picture)

영상 재생시에 재생화면을 별도의 화면으로 작게 출력하여 영상을 보면서 동시에 다른 작업을 할수 있도록 가능하게 해주는 것을 말합니다.
TV를 보면서 그 안의 작은 화면으로 다른 방송을 선택한다는 의미로 생긴용어입니다.

0 comments:

댓글 쓰기