1. 안드로이드 테이블레이아웃(tablelayout) 테두리(border) 넣기

 

border.xml

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android">

<stroke
android:width="1dp"
android:color="#ff888888" />

<solid android:color="#ffffff" />
<padding
android:bottom="8dp"
android:left="8dp"
android:right="6dp"
android:top="8dp" />


</shape>

이런식으로 drawble경로에 하나 만들어서 테이블레이아웃의 background에 적용

2. 테이블레이아웃 selector 만들기

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:state_enabled="true" android:state_pressed="false">
<shape>
<stroke android:width="1dp" android:color="#ff888888" />

<solid android:color="#ffffff" />
</shape>
</item>

<item android:state_enabled="true" android:state_pressed="true">
<shape>
<stroke android:width="1dp" android:color="#ff888888" />

<solid android:color="#ff888888" />
</shape>
</item>


</selector>



 

어플리케이션에서 디자이너의 능력이 한껏 발휘되는 다른 부분 중 또하나의 중요한 부분이 바로 안드로이드 앱의 아이콘이다.

앞서 스플래시 이미지를 만들었다고 하면 이제는 어플리케이션을 대표하는 중요한 요소인 '아이콘'을 다뤄보려 한다.


우리는 안드로이드 운영체제 위에 올라가있는 소프트웨어(앱)를 실행시키기 위해 아이콘을 클릭하고,

메시지 등의 푸쉬 알람을 수신할 때 상태바(status bar)에는 아이콘을 이용해 새로운 소식이 왔음을 확인하며,

어플리케이션 내에서는 메뉴, 탭, 다이얼로그, 리스트 등에도 아이콘이 다양하게 활용되어 UI를 장식한다.


안드로이드의 아이콘 가이드라인은 iOS(아이폰)의 아이콘만큼 깐깐하게 지킬필요는 없지만

많은 부분은 디자이너들이 그냥 이쁘게만 만들다보니 놓치게 되고 개발자가 쉽게 파악하지 못하는 경우가 생긴다.

아래의 아이콘 디자인 가이드라인과 팁을 따라서 정갈하고 정해진 틀을 지켜 앱을 대표하고 꾸미는 중요한 요소인 아이콘을 디자인하게 되면

그 앱은 아이콘이 없이 텍스트로만 이루어져있거나 미적 요소가 없는 단순한 앱보다 훨씬 풍부한 감각적 요소를 가미할 수 있을 것이다.



안드로이드 앱 아이콘/아이콘 디자인/안드로이드 디자인/UI 디자인/앱 아이콘 디자인/어플리케이션 디자인






사용자 인터페이스를 통해 통합된 모양과 느낌을 만드는 것은 당신의 앱(생산물)에 가치를 더하는 역할을 한다.

그래픽 스타일을 효율적으로 사용하게 되면 당신 앱 UI가 사용자들에게 훨씬 전문적으로 보이게 만들어 준다.

여기서는 안드로이드 2.x의 프레임워크에서 사용하는 일반적인 스타일과 매치되는 앱의 UI의 다양한 부분에서 아이콘을 만드는데

필요한 정보들을 제공할 것이고, 이 가이드라인을 따르게 되면 사용자는 멋지고 통합된 UX를 느낄 수 있을 것이다.



우선, 안드로이드 앱 전체에서 사용되는 아이콘의 일반적인 타입들에 대해서 자세한 설명을 해 보도록 하자.

자세한 내용이 보고싶으면 각 아이콘 설명 아래 있는 링크를 따라가면 된다, 제작하는 가이드라인이 구체적으로 제시되어 있다.





Launcher Icons :: 런쳐 아이콘

런처 아이콘은 디바이스의 홈스크린과 런쳐 윈도우에서 당신의 앱을 표현하는 그래픽 아이콘이다.

http://developer.android.com/guide/practices/ui_guidelines/icon_design_launcher.html





Menu Icons :: 메뉴 아이콘

메뉴 아이콘은 사용자들이 메뉴 버튼을 눌렀을 때 유저에게 옵션 메뉴에서 보여줄 그래픽 아이콘이다.

http://developer.android.com/guide/practices/ui_guidelines/icon_design_menu.html





Action Bar Icons :: 액션바 아이콘

액션바 아이콘은 액션바 상에서 액션 항목을 표현하기 위한 그래픽 아이콘이다.

http://developer.android.com/guide/practices/ui_guidelines/icon_design_action_bar.html





Status Bar Icons :: 상태바 아이콘

상태바 아이콘은 당신의 앱으로부터 전송된 알람을 상태바에 표현하기 위해 사용되는 그래픽 아이콘이다.

http://developer.android.com/guide/practices/ui_guidelines/icon_design_status_bar.html





Tab Icons :: 탭 아이콘

탭 아이콘은 멀티 탭 인터페이스 사용 시 각각의 탭에 들어갈 그래픽 아이콘이다.

http://developer.android.com/guide/practices/ui_guidelines/icon_design_tab.html





Dialog Icons :: 다이얼로그 아이콘

다이얼로그 아이콘은 사용자의 상호작용을 위한 팝업 다이얼로그 박스에 보여질 아이콘이다.

http://developer.android.com/guide/practices/ui_guidelines/icon_design_dialog.html





List View Icons :: 리스트뷰 아이콘

리스트뷰 아이콘이란 리스트 아이템들을 리스트 뷰 상에서 표현되는 아이콘이다. 설정 어플리케이션이 그 예다.

http://developer.android.com/guide/practices/ui_guidelines/icon_design_list.html









안드로이드 아이콘 템플릿 팩이란 가이드라인에 맞도록 아이콘을 쉽게 제작할 수 있게 도와주기 위해

디자인, 텍스쳐, 레이어 스타일 등을 모아놓은 하나의 패키지를 말하며, 이는 안드로이드 공식 사이트에서 제공하고 있다.


icon_templates-v4.0.zip

(http://developer.android.com/shareables/icon_templates-v4.0.zip)



안드로이드 공식 사이트에서는 아이콘을 디자인하기 이전에 템플릿 팩을 다운로드 받아 사용하는 것을 권장하고 있다.

psd형태로 제공되는 아이콘 템플릿들은 안드로이드 플랫폼의 아이콘을 제작하는데 필요한 레이어와 디자인 처리 방식등을 포함하고 있다.






안드로이드는 다양하고 넓은 범위의 스크린 사이즈와 해상도를 제공하는 여러 기기들에서 돌아가도록 설계된다.

만약 어플리케이션의 아이콘을 디자인하게 된다면, 이역시 여러 해상도의 각기 다른 기기에서 보여지게 될 것이라는 점을 기억해야 한다.

멀티플 스크린 지원 문서(링크)에 나와있듯이 안드로이드 플랫폼은 디바이스의 스크린 사이즈와 해상도에 상관없이

어떤 기기에서든 우리가 원하는 방식, 원하는 모양 그대로 적절하게 아이콘들이 표시되어야 한다.


일반적으로, 아이콘들을 각 스크린 밀도에 따라 각각 일반화된 형태의 아이콘 세트를 제공하는 방식이 추천된다.

그 이후에 그들을 각각 해상도별로 다른 리소스 폴더에 넣고 어플리케이션을 구동시키는 것이다.


어플리케이션이 실행되면, 안드로이드 기기는 실행되는 기기의 스크린 특징을 체크한 이후에

그 사이즈나 해상도에 맞는 적절한 안드로이드 아이콘을 로딩해와서 보여주게 되는 방식인 것이다.

어떻게 밀도별로 다른 리소스를 어플리케이션에 삽입하는지 잘 모르겠다면, 아래의 링크를 따라가서 확인하기 바란다.


Resource directory qualifiers for screen size and density

http://developer.android.com/guide/practices/screens_support.html#qualifiers







이제까지 아이콘의 종류와 제공방식에 대해 설명했다면,

여기서 말하는 '아이콘 디자인 팁'은 훨씬 원활하고 정형화된 디자인 작업으로 가독성 높고 팀단위로 일할때도 유용한

디자이너를 위한, 그리고 팀을 위한 아이콘 디자인 방법에 대해 조금 더 자세히 얘기해 줄 것이다.




Use common naming conventions for icon assets

제작된 아이콘들에 대해 일반적(규칙적)인 명명 규칙을 사용하라.


아이콘을 저장할 때, 이미지 파일들의 이름이 관련있는 것들끼리 디렉토리 내에서 그룹핑될 수 있도록 정하라.

특히 이것은 일반적인 prefix를 사용하여 각각의 아이콘 형태를 나타내는데 매우 유용하다.

이는 반드시 해야만 하는 것은 아니지만, 규칙을 지정해서 관리가 수월하게 하기 위한 하나의 '팁'이다.






Set up a working space that organizes files for multiple densities

여러개의 밀도를 가진 파일들을 정리하기 위한 작업 공간을 설정하라.


여러가지 해상도에서의 스크린 밀도를 지원한다는 것은, 같은 아이콘을 여러개의 다른 해상도 버전으로 만들어야 한다는 것을 의미한다.

다른 해상도의 파일 복사본들을 관리하거나 찾기 쉽게 하기 위해서, 해상도별로 파일들을 분류하는 디렉토리를 만드는 것을 추천한다.



이런 구조를 이용하면 특정한 밀도 구조에 맞춰서 앱 리소스에 완성된 아이콘들을 저장할 수 있게 된다.

당신의 작업 공간(워크 스페이스)의 구조는 실제 어플리케이션의 리소스 구조(안드로이드 개발의 디렉토리)와 매우 비슷하기 때문에,

이런 구조를 이용한다면 쉽게 어떤 아이콘들이 어플리케이션의 리소스 디렉토리로 복사되어야 하는지 결정할 수 있다.


이렇게 그들의 밀도에 따라서 제작된 결과물들을 저장하는 것은 디자이너 혹은 개발자가 쉽게 파일이름으로 구별이 가능하고

이는 다른 밀도이지만 동일한 파일 이름을 공유해야하는 경우를 쉽게 해결할 수 있다. 이는 매우 중요한 역할을 한다.


비교를 위해, 아래 나온 디렉토리 구조는 전형적인 어플리케이션 상에서의 모습을 나타낸 것이다.







Use vector shapes where possible

가능한 곳이라면 벡터를 이용하라.


포토샵과 같은 많은 이미지 편집 툴에서 벡터 요소와 래스터 레이어, 효과들을 조합하여 사용할 수 있다.

가능한 곳이라면 디테일이나 가장자리의 비트 손실 없이 사이즈 조절이 가능하도록 벡터 도형들을 사용하라.

벡터를 사용하면 작은 해상도에서도 픽셀 경계에 있는 가장자리나 모서리를 쉽게 처리할 수 있다.





Start with large artboards

처음에는 큰 그림으로 시작하라.


디자이너는 아이콘을 제작하면서 다양한 스크린 밀도에 따라 리소스를 생성해 내야 한다.

이렇기 때문에 아이콘의 가로세로 비율에 맞는 큰 artboard에서 아이콘 디자인을 시작하는 것이 가장 좋다.

예를 들어 런쳐 아이콘이 화면 밀도에 따라 96, 72, 48, 36 픽셀인데 처음에 864*864 artboard에서 런쳐 아이콘을 그리게 되면

최종적으로 만들어낼 런쳐 아이콘의 대상 크기로 줄여서 사용하게 되면 훨씬 쉽고 분명해 질 수 있는 것이다.





When scaling, redraw bitmap layers as needed

확대를 할 때에, 비트맵 레이어는 필요에 따라 다시 그려라.


벡터 레이어가 아닌 비트맵 레이어에서 이미지의 크기를 조정하게 되면

해당 레이어가 높은 밀도에서도 선명하게 보여질 수 있도록 직접 다시 그려야 할 필요성이 있다.

예를 들어 60*60 사이즈의 원이 mdpi 해상도에 맞춰서 비트맵에 그려졌다면 

새로 필요하게 된 hdpi의 90*90 사이즈 리소스는 새로 그려져야 한다.





When saving image assets, remove unnecessary metadata

이미지를 저장할 때에, 불필요한 메타데이터는 모두 제거하라.


안드로이드 SDK 툴에서 앱 리소스들을 기기가 알아들을 수 있는 이진 코드(binary)로 변환할 때 자체적으로 png를 압축하긴 하지만

더 좋은 방식은 PNG파일의 제작을 마치고 나서 불필요한 헤더나 메타데이터를 없애주는 것이다.

OptiPNG나 Pngcrush 등의 툴을 이용하면 메타데이터들을 제거할 수 있고 이미지 파일의 사이즈도 최적화 할 수 있다.





Make sure that corresponding assets for different densities use the same filenames

같은 이미지의 다른 밀도인 파일들이 같은 파일 이름을 사용하고 있는지 확인하라.


같은 이미지의, 하지만 다른 밀도를 가진 아이콘 파일은 해상도만 다를 뿐 동일한 파일 이름을 사용해야 한다.

하지만 밀도 별 리소스 디렉토리에 저장하기 때문에 파일 이름이 같다고 해서 충돌이 일어나는 일은 '당연히' 없다.

이는 안드로이드에서 지원하는 것이며 위에서 이미 언급했듯이 각 기기의 화면에 따라 시스템이 적절한 리소스를 찾아 로드한다.

이러한 이유로 각 디렉토리에 있는 이미지들의 집합은 일관성을 유지해야 하고 특정한 접미사가 붙어있어서는 안된다.


references


Android - Icon Design Guidelines

http://developer.android.com/guide/practices/ui_guidelines/icon_design.html

출처:http://baekhorang.tistory.com/entry/


 

 

넷플릭스는 전세계에 유료 가입자만 5700만명에 이르는 명실상부한 세계 최대 유료 동영상 스트리밍 서비스다.

넷플릭스는 한 달에 적게는 7.99달러만 내면 영화와 TV 프로그램과 같은 영상 콘텐츠를 맘껏 볼 수 있는 온라인 동영상 스트리밍 서비스다. 명실상부한 세계 최대 사업자로, 유료 가입자만 5700만명에 이른다. 원래 미국에서 시작된 서비스지만, 가입자 5700만 중 1800만명이 해외 구독자다. 넷플릭스는 앞으로도 미국 방송 업계 석권을 넘어 해외 시장 개척에 적극 나서 성장세를 이어나갈 기세다.

“인터넷 + 영화 = 넷플릭스”

‘넷플릭스’라는 이름은 인터넷(NET)과 영화(flicks)에서 따왔다. 리드 헤스팅즈가 넷플릭스를 창업할 당시부터 인터넷으로 영화를 유통할 생각을 꿈꾸고 있었기 때문이다. 하지만 처음부터 스트리밍 방식으로 콘텐츠를 유통한 것은 아니다. 1997년 넷플릭스는 비디오와 DVD를 우편·택배로 배달하는 서비스로 시작했다. 인터넷 스트리밍까지 사업을 확장한 건 그로부터 10년 뒤인 2007년이다.

넷플릭스는 1997년 DVD 대여 서비스로 시작했다. <사진: 위키피디아>

블록버스터를 파산시키다

리드 헤스팅스 넷플릭스 창업자

“창업자는 반드시 반대를 보는 관점(contrarian view)을 가져야 한다.” - 리드 헤즈팅스 넷플릭스 창업자

1997년 리드 헤스팅즈가 DVD 대여 서비스로 넷플릭스를 시작했을 당시 이미 미국엔 부동의 업계 강자가 있었다. 비디오 대여 체인 1위 사업자였던 블록버스터다. 블록버스터는 비디오를 빌려보는 문화가 막 움트던 1980년대를 타고 성장했다. 2005년 기준으로 미국에만 점포가 5500곳이 있었을 만큼 시장 지배자였다. 하지만 치고 올라오는 넷플릭스에게 결국 왕좌를 내주고 지난 2013년 파산했다. 골리앗 블록버스터를 상대로 신생기업이었던 넷플릭스가 어떻게 시장 구도를 뒤엎어 버렸을까.

답은 ‘역발상’에 있었다. 블록버스터의 운영 방식은 국내 비디오 대여점과 비슷했다. 빌려간 비디오를 약속한 기간 안에 반납하지 않으면 연체료를 무는 식이었다. 넷플릭스의 전략은 아예 달랐다. 연체료를 아예 없애버렸다. 그 대신 넷플릭스는 구독료를 받기 시작했다. 월 사용료를 받고 비디오를 반납했을 때 다른 비디오를 보내주는 식이니, 장기 연체하는 고객이 생길 염려도 없다.

미국 방송 산업의 역사를 새로 쓰다

넷플릭스는 OTT(Over The Top, 셋톱박스를 넘어서는) 서비스다. OTT 서비스는 별도의 셋톱박스 없이 인터넷을 통해 볼 수 있는 TV다. 최근 미국에서 OTT는 기존 콘텐츠 유통 구조를 바꾸고 있다는 평가를 받는다. 수백 개의 케이블TV 채널이 지상파 이상의 영향력을 갖고 있는 미국 시장에서 인터넷과 모바일 등을 통한 OTT 서비스들이 빠른 성장세를 보이며 기존 방송사들을 위협하고 있다. 그 행렬의 가장 앞에 있는 기업이 바로 넷플릭스다.

넷플릭스는 과거 블록버스터 시장을 잠식해 나갔던 것처럼 기존 지상파 방송과 케이블TV의 역할을 대체하고 있다. 지난 2013년에는 미국 최대 케이블방송 <HBO>의 가입자 수를 넘어섰다. 넷플릭스는 또한 돈을 지불하고 영상을 구독하는 서비스 가운데 미국에서 제일 많이 쓰는 플랫폼이다. 에릭슨이 지난 2014년 미국에서 주문형 동영상(VOD) 서비스를 이용하는 소비자 비율을 조사했더니, 넷플릭스 이용자가 전체의 50%에 달했다.

넷플릭스 이미지 1

넷플릭스 성장세를 견인한 주된 요인으로는 싼 가격을 꼽는다. 넷플릭스는 한 달에 최소 7.99달러만 내면 콘텐츠를 무제한으로 즐길 수 있다. 케이블 유료 방송 서비스 이용료는 한 달에 최소 50달러 정도이니, 3~4배는 비싸다. 게다가 케이블방송은 셋톱박스가 달린 TV 앞에서만 봐야 한다는 불편함도 있다. 하지만 넷플릭스는 윈도우 PC와 매킨토시, X박스360, 플레이스테이션3, 닌텐도 위, 애플TV, 아이패드, 아이폰, 구글TV 등 다양한 시청 환경을 지원한다.

최근에는 경쟁력이 단순히 가격에만 있진 않다. HD나 4K 등 화질 면에서도 기존 방송 플랫폼들의 장점을 흡수하고 있는 모양새다. 차세대 TV로 거론되는 4K 해상도의 초고화질TV(UHDTV)에 대처하는 일이 기존 케이블 채널보다 상대적으로 쉽기 때문이다. 넷플릭스는 전송 시스템만 적용하면 되기에, 이미 몇몇 콘텐츠에서는 4K 스트리밍을 시작했다. 하지만 케이블 채널은 UHD 방송 전송을 위해 셋톱박스뿐 아니라 전송망도 손봐야 하는 난관이 있다.

빅데이터를 활용한 추천 알고리즘

넷플릭스의 성공요인으로 꼽히는 것이 정교한 추천 알고리즘이다.

아마존의 스트리밍 서비스인 ‘아마존 인스턴트 프라임’에 제공되는 콘텐츠 수는 8만종이 넘는다. 올레TV와 같은 국내 IPTV들도 보통 10만종 이상이다. 하지만 전세계 유료 가입자 5천만명이 즐기고 있는 동영상 스트리밍 서비스 최강자 넷플릭스가 보유한 콘텐츠 수는 채 1만종도 되지 않는 것으로 알려져 있다. 10분의 1 수준의 콘텐츠 수로 어떻게 가입자를 사로잡을 수 있었을까. 비결은 ‘추천 알고리즘’이다.

적은 영상 콘텐츠로 사용자 만족도를 높이기 위해 빅데이터를 적극 활용하는 게 넷플렉스의 전략이었다. 넷플릭스가 2000년도에 내놓은 사용자의 취향을 정확히 파악해서 보고 싶은 영상을 추천해주는 알고리즘은 넷플릭스를 지금의 자리에 있게 해준 일등공신이다. 넷플릭스는 시청자에게 영상마다 별점을 매기게 한 뒤 평점을 기반으로 그 시청자가 선호하는 영상들 사이의 패턴을 분석해 그 다음에 볼 영상을 미리 알아맞힌다.

넷플릭스의 알고리즘은 적은 콘텐츠를 효율적으로 사용할 수 있게도 해줄 뿐 아니라 광고 효과라는 엄청난 이득도 있다. 콘텐츠 제작사 입장에선 자신들의 잠재 시청자에게 더 잘 도달할 수 있기 때문이다. 실제로 관심이 있는지 없는지도 확실치도 않은 대중을 상대로 광고비를 쏟는 것보다 넷플릭스 알고리즘대로 정말 그 영상을 볼만한 시청자에게 추천을 해주는 게 훨씬 효과적일 것이다.

그래서 넷플릭스는 추천 알고리즘에 투자를 아끼지 않는다. 추천 알고리즘을 더 정교화하기 위해서 추천 알고리즘 대회인 ‘넷플릭스 프라이즈’를 2006년부터 3년 동안 개최하기도 했다. 넷플릭스는 이 대회에서 추천 알고리즘의 정확도를 10% 향상시킬 수 있는 팀에 100만달러, 우리돈으로 10억원이 넘는 상금을 내걸었다. 최근에는 한발짝 더 나가 컴퓨터가 마치 사람처럼 생각하고 배울 수 있도록 하는 기술인 ‘딥러닝’도 도입했다.

빅데이터를 활용한 컨텐츠 기획/제작

넷플릭스가 자체 제작한 드라마 ‘하우스 오브 카드’

넷플릭스는 콘텐츠를 유통하는 플랫폼으로만 유명하진 않다. 성공한 콘텐츠 생산자이기도 하다. 넷플릭스는 2012년부터 콘텐츠를 제작사에서 구매해 제공하는 걸 넘어 자체적으로 콘텐츠를 만들어내기 시작했다. 빅데이터 강자인 넷플릭스는 콘텐츠를 만들 때도 빅데이터를 활용했다. 넷플릭스는 미국 시장 안에서 구독자의 선호도를 철저히 분석한다. 기획부터 주인공 섭외, 배급까지 전반에 걸쳐 빅데이터 분석을 활용한다.

대표적인 사례가 [하우스 오브 카드]다. 이 작품은 1990년에 영국 <BBC>에서 제작된 같은 이름의 드라마를 원작 삼아 리메이크했다. 넷플릭스는 데이터 마이닝을 통해 시청자의 성향을 파악한 뒤 그들이 원하는 연출 스타일이나 좋아할 만한 배우 등을 예측해 섭외했다. 분석은 적중했다. [하우스 오브 카드] 시즌1이 공개된 뒤 시청자 가운데 85%가 만족했다. 또한 에미상 3관왕의 영예를 안았을 만큼 대중성과 작품성 모두 인정받았다.

[하우스 오브 카드]가 대박나며 콘텐츠 제작사로 성공적으로 연착륙한 넷플릭스는 [오렌지 이즈 더 뉴 블랙], [마르코 폴로] 등 콘텐츠 제작사로서의 행보에 더욱 열을 내는 모습이다. 투자도 아끼지 않는다. 최근 넷플릭스가 선보인 [마르코 폴로]는 여태껏 나온 TV 드라마 가운데 가장 제작비를 많이 쓴 축에 속한다고 <뉴욕타임즈>는 전했다. [마르코 폴로]의 10편 제작비는 9천만달러에 이른다. 우리돈으로 1천억원이 넘는 거액이다.

“최종적으로 넷플릭스는 세계 최대 콘텐츠 제작사가 될 것이다.” - 테드 사란도스 넷플릭스 최고 콘텐츠 책임자
참고자료

· 넷플릭스의 빅 데이터(Big Data), 인문학적 상상력과의 접점, 조영신 SK 경영경제연구소 수석연구원
· 오! 넷플릭스가 일깨워준 질문들, 미디어토핑(http://mediatopping.com/2015/01/21/oh-netflix-nothing-but-netflix/)
· [IT탐구영역] 넷플릭스, 블로터(http://www.bloter.net/archives/219437)
· 미국 콘텐츠 산업 동향, 한국콘텐츠진흥원 미국사무소

 

출처:http://navercast.naver.com/contents.nhn?contents_id=82499

● Composite 중에서 GridView를 살펴보겠습니다. 이것 역시 다른 객체와 함께 사용해서 화면을 구성하게 되는데요. 지난 포스팅에서 작성한 리스트뷰가 행으로 아이템을 출력했다면 이것은  가로, 세로 2차원으로 아이템을 배치하고 스크롤하면서 아이템을 탐색할 수 있습니다. 이것 또한 "ListAdapter"를 이용하여 매핑하는 방식으로 구현을 하는데요. 


예제를 하나 만들면서 자세히 보겠습니다.

 

 

● 간단한 프로젝트를 하나 만들건데요. 위 그림처럼 단말기에 있는 앱의 아이콘과 이름을 아이템으로 그리드뷰로 출력하고, 아이콘을 클릭하면 앱에 대한 설명이 Toast를 통해 출력되고 어플이 실행되며, "뒤로" 버튼을 누르면 다시 돌아오는 기능을 구현하겠습니다. 즉 내가 만든 어플(GrideView)에서 "인텐트"를 이용해서 다른 어플을 실행할 수 있는점을 살펴보겠습니다.

 

● 이 프로젝트는 세개의 파일이 필요하겠네요. activity_mainj.xml 파일에는 그리드뷰 를 배치하고, item.xml파일을 하나 만들어서 출력할 아이템에 대한 레이아웃을 정의하고, MainActivity.java에서 단말기의 어플 목록을 가져와서 그리드뷰에 출력하는 데이터셋으로 이용하고, 이것들을 매핑하는 어댑터 클래스를 생성하여 적용하게 됩니다.

 

● 먼저 activity_main.xml파일에" GridView"를 배치하겠습니다.

 

 

● xml 소스코드를 살펴보겠습니다.

 

 

android:numColumns를 "auto_fit"으로 설정하여 아이템의 크기에 따라 자동으로 '열'의 수가 조정되게 하고 있구요. android:stretchMode를 "columnWidth"로 설정하여 아이템들의 '열' 폭을 자동으로 조절되게 하고 있습니다.

 

 

● 다음으로 그리드뷰에 매핑할 아이템의 레이아웃을 정의할 item.xml파일을 작성하겠습니다. 여기에는 어플의아이콘을 출력할 ImageView와 이름을 출력할 TextView가 배치가 됩니다.

 

이미지뷰의 크기를 큰 아이콘의 크기인 "72px"로 정의하고 있으며, 이름을 출력할 TextView가 중앙에 배치되도록 layout_gravity를 "center"로 설정하고, 텍스트뷰안에 있는 글자들이 중앙에 배치되도록 gravity를 "center"로 설정하고 있습니다. lines="1"은 이름이 한줄로만 표시되도록 하는 것이고, ellipsize를 "end"로 설정하는 것은 이름이 길때 "..."으로 줄임표시 하기 위한 것입니다.

 

 

 

● 이제 단말기에 설치된 어플 목록을 가져와서 실행하고, 그리드뷰에  목록을 출력하는 내용을 MainActivity.java파일에 작성하겠습니다.

 이 클래스에는 또 다른 클래스(gridAdapter)가 작성이 될것입니다. 하위 클래스에서도 사용할 수 있도록 액티비티, GridView, 앱 정보를 기록할 List, 앱을 제어할 PackageManager 변수들을 전역변수로 선언하고 있습니다.

 

 

● 다음으로 Intent와 어댑터 클래스를 작성합니다.

위 내용중 첫번째 박스의 경우 인텐트를 통해서 앱의 목록을 가져오기 위해서 "Intent.ACTION_MAIN"으로 인텐트를 생성하고, 실행 정보를 얻기 위해 "Intent.CATEGORY_LAUNCHER"를 카테고리로 추가하고 있습니다. 패키지 관리자를 호출해서 앱 정보를 요청하고 이것을 "app"객체에 담고 있으며, 그리드뷰 객체를 찾아와서 아래쪽 클래스에서 정의할 목록 어댑터를 적용하고 있습니다.

 

다음으로 두번째 박스에서는 위쪽에서 적용한 gridAdapter 클래스를  BaseAdapter클래스를 상속받아서  작성합니다. 아이템 레이아웃 파일을 매핑하기 위해서 LayoutInflater객체를 선언하고 생성자를 정의하고, 출력할 목록 수 계산, 아이템을 호출하는 메서드, 아이템의 아이디를 구할 메서드를 정의하고 있습니다.

 

 

 

 

● 다음으로 그리드뷰에 앱 정보와 아이템 레이아웃을 매핑하는 메서드를 작성하겠습니다.

 

1. 아이템뷰의 아이템 레이아웃을 재활용 하는 방식으로 구현하고 있는데요. 이 메서드에서 아이템뷰는 "contvertView"에 해당이 되는데, 이 객체가 아직 생성이 되지 않은 경우에는 LayoutInflater를 이용하여 item.xml파일을 호출하여 아이템뷰의 객체를 생성하도록 하고 있습니다.

 

2 위에서 구한 앱목록(apps)에서 이 메서드에서 매핑할 한개의 어플 정보만 추출하고 ResolveInfo형의 "info"라는 객체에 기록하고 있습니다. 이 정보는 아래쪽에서 클릭이벤트에서도 사용하기 위해서 final로 선언을 하고 있습니다.

 

3. ImageView, TextView 객체를 찾아서 각각 아이콘과 이름을 대입하고 있습니다.

 

4. 이미지뷰를 클릭하면 해당 앱이 실행되도록 클릭 이벤트를 작성하고 있는데요. "Intent.ACTION_RUN"으로 인텐트를 생성하고, "ComponentName"으로 해당 어플 실행 객체를 불러와서 그 어플의 액티비티를 실행하도록 하고 있습니다. 이렇게 하면 현재 만들고 있는 앱에서 다른 앱들을 실행을 할 수 있게 됩니다. 그리고 "BACK" 버튼을 누르면 다시 GridView 어플로 돌아오게 하고 있습니다. 여기서 알 수 있는 한가지는 어떤 어플을 실행하기 위해서는 그 앱의 패키지 정보와 시작하는 액티비티 클래스의 이름을 알아야 하는데, 이것들을 ResolveInfo.activityInfo를 통해서 구할 수 있다는 점입니다.

마지막으로 새로 실행시키는 앱의 정보(패키지이름, 액티비티 클래스 이름)를 Toast를 이용해서 출력하도록 하고 있습니다.

 

 

 

● 이제 AVD에서 실행을 해보겠습니다.

 

 

 ● 지금까지 만든 GridView 앱을 실행을 해보면 위와 같이 AVD에 설치되어 있는 어플들의 목록이 나타나게 되고, 이것들을 클릭하면 "Toast"를 통해서 그 앱의 패키지 이름과 액티비티 클래스 이름이 출력이 되면서 실행을 하게 됩니다. 실행을 하다가 "뒤로" 버튼을 누르면 다시 돌아오는 것을 확인 할 수 있습니다. 이부분에서인텐트가 자신의 앱에서만 적용되는 것이 아니라  다른 앱까지도 적용이 된다는 것을 알 수 있습니다.

 Pixel Densities

Android icons require five separate sizes for different screen pixel densities. Icons for lower resolution are created automatically from the baseline.

mdpi (Baseline):

160 dpi

hdpi:

240 dpi

1.5×

xhdpi:

320 dpi

xxhdpi:

490 dpi

xxxhdpi:

640 dpi

 

 

Sizes (px)

Format and naming

Notes

 Launcher icons

 48 × 48 (mdpi)

 .png

 Three-dimensional, front view, with a slight perspective as if viewed from above, so that users perceive some depth.

 72 × 72 (hdpi)

 96 × 96 (xhdpi)

 144 × 144 (xxhdpi)
 192 × 192 (xxxhdpi)
 512 × 512 (Google Play store)
    

 Action bar, Dialog & Tab icons

 24 × 24 area in 32 × 32 (mdpi)

 png

These icons are used in the action bar menu. The first number is the size of the icon area, and the second is file size.

 36 × 36 area in 48 × 48 (hdpi)

 48 × 48 area in 64 × 64 (xhdpi)

 72 × 72 area in 96 × 96 (xxhdpi)

 96 × 96 area in 128 × 128 (xxxhdpi)

 

 Small Contextual Icons

 16 × 16 (mdpi)

 png

Small icons are used to surface actions and/or provide status for specific items. For example, in the Gmail app, each message has a star icon that marks the message as important.
 24 × 24 (hdpi)
 32 × 32 (xhdpi)
 48 × 48 (xxhdpi)
 64 × 64 (xxxhdpi)

 Notification icons

 22 × 22 area in 24 × 24 (mdpi)

 png

These are used to represent application notifications in the status bar. They should be flat (no gradients), white and face-on perspective

 33 × 33 area in 36 × 36 (hdpi)
 44 × 44 area in 48 × 48 (xhdpi)
 66 × 66 area in 72 × 72 (xxhdpi)

 88 × 88 area in 96 × 96 (xxxhdpi)



 

다음지도 api Guide


먼저, 압축을 풀면 위와 같이 폴더가 구성이 되어 있습니다. 그러면 아래와 같이 main 폴더에서 오른쪽 클릭한 후 [New]-[Directory]를 선택합니다.

 

 

 그런 다음 jniLibs라고 폴더를 만듭니다.

 

그 후 두 폴더를 jniLibs 폴더 밑으로 옮깁니다.(여기에선 jar파일을 먼저 옮겼는데 이런 순서는 크게 상관이 없습니다.)
 

그리고 libs폴더가 기존에 있을텐데요.  이 폴더 밑으로 jar파일을 옮깁니다.



 이런식으로 압축파일에 있던 파일을 추가한 후에 다음과 같이 추가합니다.
< uses-permission android:name="android.permission.INTERNET" />
< uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />



 

 


 

위와 같이 되어 있는 build.gradle을 아래와 같이 추가합니다.
compile fileTree(dir: 'libs', include: ['*.jar'])
compile files('libs/libDaumMapAndroid.jar')
 

마지막으로 위에 있는 메뉴 중 [sync gradle]를 클릭하여 변경한 gradle을 적용시킵니다.





그리고 사용해본 바로는 이 방법이 좀더 쉬운 편이고 편하게 할 수 있었습니다.

 

'Android' 카테고리의 다른 글

무료로 제공하는 아이콘들  (0) 2016.01.06
Android check permission for LocationManager  (0) 2016.01.04
<Android> GPS 위도,경도,주소 불러오기  (0) 2015.12.28
Fragment animation 효과  (0) 2015.12.24
List View 상세페이지  (0) 2015.12.24
/**
 * Android 위치 정보
 * ------------------------------------
 * 1) 퍼미션 추가 : android.permission.ACCESS_FILE_LOCATION
 * ------------------------------------
 * (구현절차)
 * 
 * 1. onCreate --> GPS를 제어할 수 있는 LocationManager 객체 생성
 *   1) 현재 사용 가능한 위치 정보 장치 중에서
 *       가장 정확도 높은 장치를 판별
 *   2) 마지막으로 조회되었던 위치 정보(위도,경도)가 존재하는지
 *      체크하고, 있다면 그 위치로 초기값 설정 
 * 
 * 2. onResume에서 GPS를 구동
 *  --> LocationManager 객체에 이벤트 연결
 *   위치정보 장치 이름, 갱신 기간 주기, 갱신 거리 주기를 설정
 * 
 * 3. onPause에서 GPS를 중지
 *   --> LocationManager 객체에 이벤트 해제
 * */


package itwill.ucity.locationex;

import java.util.List;
import java.util.Locale;

import android.app.Activity;
import android.content.Context;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity implements LocationListener{
 
 TextView tv1 = null;
 TextView tv2 = null;
 
 //위치정보 객체
 LocationManager lm = null;
 //위치정보 장치 이름
 String provider = null;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  tv1 = (TextView)findViewById(R.id.textView1);
  tv2 = (TextView)findViewById(R.id.textView2);
  
  /**위치정보 객체를 생성한다.*/
  lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
  
  /** 현재 사용가능한 위치 정보 장치 검색*/
  //위치정보 하드웨어 목록
  Criteria c = new Criteria();
  //최적의 하드웨어 이름을 리턴받는다.
  provider = lm.getBestProvider(c, true);
  
  // 최적의 값이 없거나, 해당 장치가 사용가능한 상태가 아니라면, 
  //모든 장치 리스트에서 사용가능한 항목 얻기
  if(provider == null || !lm.isProviderEnabled(provider)){
   // 모든 장치 목록
   List<String> list = lm.getAllProviders();
   
   for(int i = 0; i < list.size(); i++){
    //장치 이름 하나 얻기
    String temp = list.get(i);
    
    //사용 가능 여부 검사
    if(lm.isProviderEnabled(temp)){
     provider = temp;
     break;
    }
   }
  }// (end if)위치정보 검색 끝
  
  /**마지막으로  조회했던 위치 얻기*/
  Location location = lm.getLastKnownLocation(provider);
  
  if(location == null){
   Toast.makeText(this, "사용가능한 위치 정보 제공자가 없습니다.", Toast.LENGTH_SHORT).show();
  }else{
   //최종 위치에서 부터 이어서 GPS 시작...
   onLocationChanged(location);
   
  }
 }
 /** 이 화면이 불릴 때, 일시정지 해제 처리*/
 @Override
 public void onResume(){
  //Activity LifrCycle 관련 메서드는 무조건 상위 메서드 호출 필요
  super.onResume();
  
  //위치정보 객체에 이벤트 연결
  lm.requestLocationUpdates(provider, 500, 1, this);
 }
 /** 다른 화면으로 넘어갈 때, 일시정지 처리*/
 @Override
 public void onPause(){
  //Activity LifrCycle 관련 메서드는 무조건 상위 메서드 호출 필요
  super.onPause();
  
  //위치정보 객체에 이벤트 해제
  lm.removeUpdates(this);
 }

 /** 위치가 변했을 경우 호출된다.*/
 @Override
 public void onLocationChanged(Location location) {
  // 위도, 경도
  double lat = location.getLatitude();
  double lng = location.getLongitude();
  
 /* // String이외의 데이터 형을 String으로 변환하는 메서드
  tv1.setText(String.valueOf(lat));
  // String이외의 데이터 형을 String으로 변화하는 꼼수~!!
  tv2.setText(lng +""); */
  
  // String이외의 데이터 형을 String으로 변환하는 메서드
  tv1.setText(String.valueOf(lat) + " / " + String.valueOf(lng));
  // String이외의 데이터 형을 String으로 변화하는 꼼수~!!
  tv2.setText(getAddress(lat, lng));

 }
 @Override
 public void onProviderDisabled(String provider) {
  // TODO Auto-generated method stub
  
 }
 @Override
 public void onProviderEnabled(String provider) {
  // TODO Auto-generated method stub
  
 }
 @Override
 public void onStatusChanged(String provider, int status, Bundle extras) {
  // TODO Auto-generated method stub
  
 }
 
 /** 위도와 경도 기반으로 주소를 리턴하는 메서드*/
 public String getAddress(double lat, double lng){
  String address = null;
  
  //위치정보를 활용하기 위한 구글 API 객체
  Geocoder geocoder = new Geocoder(this, Locale.getDefault());
  
  //주소 목록을 담기 위한 HashMap
  List<Address> list = null;
  
  try{
   list = geocoder.getFromLocation(lat, lng, 1);
  } catch(Exception e){
   e.printStackTrace();
  }
  
  if(list == null){
   Log.e("getAddress", "주소 데이터 얻기 실패");
   return null;
  }
  
  if(list.size() > 0){
   Address addr = list.get(0);
   address = addr.getCountryName() + " "
     + addr.getPostalCode() + " "
     + addr.getLocality() + " "
     + addr.getThoroughfare() + " "
     + addr.getFeatureName();
  }
  
  return address;
  
  
  
 }
 
 

}



참조:http://andriod77.blogspot.kr/2014/08/gps_29.html

 

I think it's not the beautifulest way but this is what i did to solve it:

Fragment:

Intent intent = new Intent(activity, FragmentActivity.class);
Bundle bundle = ActivityOptions.makeCustomAnimation(activity, R.anim.slide_in_left, R.anim.slide_out_left).toBundle();
activity.startActivity(intent, bundle);
activity.finish();

FragmentActivity:

Intent intent = new Intent(this, Activity.class); // the activity that holds the fragment
Bundle bundle = ActivityOptions.makeCustomAnimation(this, R.anim.slide_in_right, R.anim.slide_out_right).toBundle();
startActivity(intent, bundle);

The disadvantage might be to save everything in the activity that is holding the fragment.

http://stackoverflow.com/questions/18810994/no-animation-when-switching-from-fragment-to-activity-and-back

+ Recent posts