태그 보관물: 라이브러리

안드로이드 외부 라이브러리 뷰 스타일 변경하기

안드로이드는 뷰의 크기, 색 등의 각종 스타일과 관련된 설정은 외부 파일(dimens.xml, colors.xml 등)에 저장해서, 한번에 많은 뷰의 스타일을 변경할 수 있도록 한다. 이 방법을 사용해서 테마나 스타일을 쉽게 변경할 수 있게 한다.

만약 앱과 라이브러리에서 동일한 속성 값을 사용한다면, 앱에서 정의한 속성을 사용한다. 그래서, 이 방법을 사용해서 외부 라이브러리 뷰의 스타일을 변경하는 방법을 살펴보겠다. 대부분의 라이브러리는 뷰의 속성을 외부 파일에 정의해서 릴리즈를 하지만, 속성값을 하드코딩한 경우에는 스타일 변경이 쉽지 않다.

라이브러리의 스타일을 변경하는 예제로, AboutLibraries(https://github.com/mikepenz/AboutLibraries)를 사용해 보자. 이 라이브러리가 사용하는 각종 스타일 값들을 살펴보고, 레이아웃에서 정의한 값들을 사용하는 부분과 이 정의 값을 변경해서 UI를 변경하는 예제를 살펴보자.

1. 스타일(styles.xml)

이 파일은 https://github.com/mikepenz/AboutLibraries/blob/develop/library/src/main/res/values/styles.xml 에서 확인 할 수 있다. 이 파일에서 앱이나 라이브러리의 스타일을 확인 할 수 있다. 아래는 스타일 파일에서 기본 스타일로 정의한 부분이다. 다른 앱들과 거의 비슷하다.

   


그러나, “AboutLibraries specific values” 주석아래를 살펴보면, item name=”about_libraries_window_background” 와 같이 커스텀 값이라는 것을 알 수 있다. 커스텀 값은 속성 파일(attrs.xml)에 정의해서 사용 할 수 있다. 속성 파일을 살펴보자.

2. 속성(attr.xml)

이 파일에서는 https://github.com/mikepenz/AboutLibraries/blob/develop/library/src/main/res/values/attrs.xml 에서 확인 할 수 있다. 이 파일은 안드로이드 앱이나 라이브러리에서 커스텀으로 사용하는 요소나 속성을 정의하는 용도이다. 이 내용은 XML 스키마를 정의해 봤다면 쉽게 이해가 갈 것이다. 하지만, 안드로이드에서 읽어들이는 값들이 정의되어 있기에, 이름과 포맷만 기술하게 되어 있긴 하다. 아래는 라이브러리에서 커스텀으로 정의한 속성의 일부이다.

 

 	
 	
 	
 	
 	
 	
 	
 	
 	
 	

위 속성에서 “about_libraries_window_background”는 색이고 참조(reference)라는 것을 알 수 있다. 다음으로 색을 살펴보자.

3. 색(colors.xml)

이 파일은 https://github.com/mikepenz/AboutLibraries/blob/develop/library/src/main/res/values/colors.xml 에서 확인 할 수 있다. 아래는 라이브러리가 사용하려고 정의한 색들 중에 일부이다.

 

#ECECEC
#FAFAFA
#212121
#727272
#212121
#AAA
#DADADA

색의 이름이 속성 파일에 정의한 이름으로 요소는 color로 시작하는 것을 알 수 있다.

4. 크기 정의(dimens.xml)

이 파일은 https://github.com/mikepenz/AboutLibraries/blob/develop/library/src/main/res/values/dimen.xml 에서 확인 할 수 있다. 이 파일은 안드로이드에서 뷰의 마진, 여백, 폰트 크기 등의 값을 정의한다. 이 라이브러리의 크기 값들은 아래와 같다.

 


12dp
72dp
20sp
14sp

16dp
16dp

이제 위 속성을 변경하지 않은 화면은 아래와 같다.

다음으로 속성을 변경하면, 어떤 UI가 변경되는지 살펴보기 위해서 간단하게 레이아웃 파일을 살펴보자.

5. 레이아웃 확인

이제 레이아웃 파일에서 개별 뷰의 스타일이 위에서 사용하는 속성을 사용하는지, 그리고 이 속성을 변경해서 뷰를 수정해 보자.

– 목록 컨테이너
목록 컨테이너는 https://github.com/mikepenz/AboutLibraries/blob/develop/library/src/main/res/layout/fragment_opensource.xml 에 정의되어 있다. 목록을 보여주는 컨테이너로 리사이클러뷰(RecyclerView)를 사용하고, 패딩 값으로 dimens.xml 파일에 정의한 속성 값을 사용하는 것을 알 수 있다. 이 속성 값을 변경해서 카드 레이아웃이 조금 좁거나 넓게 보이게 할 수 있다.

 

– 헤더 부분
목록의 헤더 부분(앱 아이콘, 이름, 버전 정보 등)은 https://github.com/mikepenz/AboutLibraries/blob/develop/library/src/main/res/layout/listheader_opensource.xml 에 정의되어 있다. 아래는 이 파일에서 앱 아이콘, 이름, 버전을 보여주는 일부 뷰이다. 여기에서도 이미지 크기는 dimens.xml 파일에 정의되어 있고, 앱 이름과 버전도 정의한 것을 알 수 있다.

 



– 항목(Item) 부분
목록의 항목은 https://github.com/mikepenz/AboutLibraries/blob/develop/library/src/main/res/layout/listitem_opensource.xml 에 정의되어 있다. 아래는 라이브러리 이름과 개발자 이름을 보여주는 부분이다. 여기도 목록의 헤더와 같이 textSize를 dimen.xml 에서 정의한 값으로 사용한다.

 


6, UI 변경 예제

이제 앱에서 텍스트 크기를 변경해서, 이 라이브러리 뷰가 사용하는 텍스트뷰의 스타일을 변경해 보자. 개발중인 앱의 앱 모듈에서 크기 정의 파일(/app/src/main/res/values/dimens.xml)을 열어서 아래의 값을 추가해 보자.

 
16sp
16sp

위 속성을 추가한 뒤의 결과는 아래와 같다.

다음으로 위에서 정의한 속성 파일의 사용자 정의 색을 변경해 보자. 개발중인 앱의 앱 모듈에서 크기 정의 파일(/app/src/main/res/values/color.xml)을 열어서 아래의 값을 추가해 보자.

 
#0368A1
#FBBB00

위에서 변경한 색이 어떻게 적용되는지 확인하려면, 라이브러리 코드를 보면 쉽게 확인할 수 있다. 예로, 헤더의 앱 이름 색을 변경하는 코드는  https://github.com/mikepenz/AboutLibraries/blob/develop/library/src/main/java/com/mikepenz/aboutlibraries/ui/item/HeaderItem.java 에서 알 수 있다. 이 클래스에서 아래의 코드로 앱 이름 텍스트뷰의 텍스트 색을 변경하는 것을 알 수 있다.

aboutAppName = (TextView) headerView.findViewById(R.id.aboutName);
aboutAppName.setTextColor(UIUtils.getThemeColorFromAttrOrRes(headerView.getContext(), R.attr.about_libraries_title_description, R.color.about_libraries_title_description));

뷰를 가지는 대부분의 안드로이드 라이브러리는 위와 거의 비슷한 구조이다. 그래서 외부 라이브러리를 개발하는 앱의 스타일에 맞춰서 사용하려면, 이 글의 과정으로 쉽게 스타일을 변경할 수 있다.

안드로이드 스튜디오 앱 프로젝트가 사용하는 외부 라이브러리 최신 버전 확인하기

안드로이드 스튜디오를 사용해서 앱을 빌드하는 데는 그레들(Gradle)을 사용하고 있다. 그리고 작게는 몇 개에서 많게는 십수 개의 라이브러리를 사용하는 앱들을 흔하게 볼 수 있다. 물론 내가 개발하고 유지하는 앱들도 여러 개의 외부 라이브러리를 사용하고 있다.

이렇게 외부 라이브러리를 사용하다 보니, 개별 라이브러리의 최신 버전을 확인해야 하는 경우가 종종 있다. 이런 경우 라이브러리 프로젝트의 소스(대부분의 경우 Github에서 호스팅하고 있다)를 확인해서 버전이 업데이트 되었으면, 다시 동기화 하고 빌드해서 앱을 확인한다.

이 과정에서 라이브러리 업데이트는 필연으로 발생할 수 있는 문제지만, 라이브러리가 업데이트 되었는지 확인하는 작업은 아주 불편하다. 그래서 안드로이드 스튜디오에서 앱이 사용하는 라이브러리의 최신 버전을 확인할 수 있는 방법을 살펴보자. 인터넷으로 확인해본 결과 플러그인을 사용하는 방법, 안드로이드 스튜디오에서 지원하는 린트(Lint)를 사용하는 방법 그리고 젯브레인에 등록된 라이브러리를 사용하는 방법이 있다.

1. 플러그인을 사용하는 방법

https://github.com/ben-manes/gradle-versions-plugin 사이트에서 플러그인을 다운로드 받아서 설치해서 사용하면 된다.

1.1 예제 Build.xml

apply plugin: 'com.android.application'
apply plugin: 'com.github.ben-manes.versions'

buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'com.github.ben-manes:gradle-versions-plugin:0.12.0'
    }
}

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "net.sjava.testapp"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile('com.mikepenz:materialdrawer:5.2.5@aar') {
        transitive = true
    }

    compile('com.mikepenz:aboutlibraries:5.6.6@aar') {
        transitive = true
    } 
}

1.2 실행

아래의 명령으로 프로젝트가 사용하는 라이브러리의 최신버전을 확인할 수 있다. 그리고 outputFormatter로 xml이나 json을 선택할 수 있다.
C:\dev\TestApp>gradlew dependencyUpdates -Drevision=release -DoutputFormatter=plain

1.3 결과

위 build.xml의 외부 라이브러리 확인결과, 아래와 같이 최신버전이 존재하는 것을 알 수 있다. 그리고, 맨 아래에 리포팅 결과를 txt파일로 저장했다는 것도 알 수 있다.

------------------------------------------------------------
:app Project Dependency Updates (report to plain text file)
------------------------------------------------------------
                                      
The following dependencies are using the latest release version:
 - com.github.ben-manes:gradle-versions-plugin:0.12.0
 - junit:junit:4.12                   
                                      
The following dependencies exceed the version found at the release revision level:
 - com.mikepenz:aboutlibraries [5.6.6  24.0.0-alpha2]
 - com.mikepenz:materialdrawer [5.2.5 -> 5.2.6]
                                      
Generated report file C:\dev\TestApp\app\build/dependencyUpdates/report.txt

2. 린트를 사용하는 방법

안드로이드 스튜디오에서 외부 라이브러리의 최신 버전을 쉽게 확인할 수 있게 린트를 사용해서 최신 버전을 확인할 수 있는 기능을 제공한다. 안드로이드 스튜디오에서 린트로 사용할 수 있지만, 기본으로 선택되어 있지 않아서 설정에서 추가한다.

2.1 린트 옵션 추가

안드로이드 스튜디오에서 Setting > Editor > Inspections 에러 아래와 같이 Newer로 찾으면 Newer Library Versions Available 옵션을 확인할 수 있고, 이 옵션을 선택하자.
setting_screen

2.2 린트를 실행해서 최신 버전의 라이브러리 확인

린트를 실행하는 방법은 상단 메뉴에서 Analyze > Run Inspection by Name…을 선택하고, Enter inspection name 창이 나오면 Newer 를 입력하면 Newer Library Versions Available을 선택할 수 있다. 그리고 Whole 프로젝트를 범위로 선택해서 확인하면, 아래와 같은 결과를 확인할 수 있다.
lint_result

3. 안드로이드 스튜디오 플러그인

안드로이드 스튜디오는 젯브레인(JetBrains)에 배포되어 있는 플러그인을 사용할 수 있다. 그래서 Setting > Plugins > Browse Repositories에 가서 version을 검색하면 Dependencies Version Checker 플러그인을 확인할 수 있고, 이 플러그인을 설치하고 안드로이드 스튜디오를 다시 시작하자. 현재 이 플러그인은 의존성 에러(안드로이드 2.1.1 버전에서 확인)로 사용할 수 없었다.

라이브러리의 의존 라이브러리에 대해서..

라이브러리..
 이넘 덕분에 프로그래밍이 많이 쉬워졌죠.. 특히, 자바진영에서는 Apache 재단의 지원이 매우 강력한 힘이 되고 있는게 현실이죠..
라이브러리를 사용하기 위해서는 의존하고 있는 라이브러리도 함께 있어야 제대로 동작을 하겠죠..
그리고, 라이브러리는 자신을 사용하는 클라이언트에게 에러 상황(Exception)에 대한 내용도 알려주겠죠?..

ㅎㅎ
위 상황을 가정하면, 왜 라이브러리가 로깅을 해야 될까요??
로깅이 debugging을 위한 거라고 가정을 한다면, 그 몫은 에러 상황을 리턴받은 클라이언트 몫이 아닐까요??

흠.. 정답이 없어서 모라 하긴 그렇지만..
개인적으로 라이브러리가 로깅을 하는것은 좋지 않다고 생각을 하는데..
혹시 저와 다른 생각이 있으신 분들은 답글 좀..  ^^