인디노트

앨범북 안드로이드 버전 2.0 개발 - 상단 상태바(Status Bar) 표시 및 투명처리 본문

소스 팁/Java, Android, Kotlin

앨범북 안드로이드 버전 2.0 개발 - 상단 상태바(Status Bar) 표시 및 투명처리

인디개발자 2016. 10. 2. 18:01

앨범북 1.0 버전은 상단에 상태바 (Status Bar) 가 없이 전체 화면 (Full Screen) 을 사용했다.

다음 코드와 같이 천체 화면을 사용하도록 하였다.

@Override

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE);

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

setContentView(R.layout.book_list_activity);


이와 같이 코드를 작성하면 아래의 그림과 같이 앱이 천체 화면을 사용할 수 있다. 이것은 안드로이드 버전과 상관없으며 모든 안드로이드 버전에서 편리하게 전체 화면을 사용하도록 하는 앱을 만들 때 유용하다.

버전 2 부터 상단에 상태바 (Status Bar) 를 넣으려고 한다. 참고적으로 아이폰용 앱범북 2.0 을 다음과 같은 UI 로 새롭게 디자인 하여 앱 스토어에 등록하였다.

가장 큰 변화는 상단 상태바 (Status Bar) 및 앨범의 북 모양 및 받침대 그리고 이름표를 표현하였다. 아이폰 화면의 크기 기준으로 한줄에 3 개의 북이 배치되도록 북 사이즈도 조절 하였다. 아이패드의 경우에는 한줄에 6 개 정도 보인다.


우리는 이제, 앨범북 안드로이드 버전을 아이폰 버전 2 처럼 메인 UI 를 Renewal (리뉴얼) 하려고 한다.


우선, 상태바를 감추는 코드를 다음과 같이 주석 처리하여 상태바가 보이도록 한다. 물론 해당 라인을 소스에서 제거해도 상관 없다.

requestWindowFeature(Window.FEATURE_NO_TITLE);

// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);


Oops~~~ 이렇게 상단에 바라던 상태바는 표시되었지만...

우리의 최종 목표는 상태바를 투명하게 표시하며 그 아래에 북 리스트는 전체 화면에 표시하지만 북리스트를 위로 스크롤 했을 때 북 리스트가 상태바의 아래쪽으로 흘러가는게 보이도록 하는 것이다.

휴~~~ 앱 화면 상황을 글로만 표현 하자니 표현이 좀 까다롭다.


이제 앱에 투명한 테마(Theme)용 리소스(theme.xml)를 추가 할 것이며, AndroidManifest.xml 파일에 해당 테마(Theme)를 사용하도록 코드를 추가 할 것이다.

우선 res/values/theme.xml 파일을 추가 하여 다음과 같은 내용으로 입력한다. 물론, 이미 해당 theme.xml 파일이 있거나 theme 용 xml 파일이 별도로 준비 되어 있다면 그 파일의 내용을 수정하여 적용하면 된다.

<resources>

    <!-- Make the status bar traslucent -->

    <style name="AppTheme" parent="AppBaseTheme">

        <item name="android:windowTranslucentStatus">true</item>

    </style>

</resources>

테마의 이름을 AppBaseTheme 라고 정하고, BookListActivity 에 적용해 보도록 하겠다.

AndroidManifest.xml 파일에 다음과 같은 라인을 추가한다.

<activity android:name="org.smartdisk.album.book.BookListActivity"

android:label="@string/app_name"

android:theme="@style/AppTheme"

android:launchMode="singleTask"

>

Ohh~~~. 어느 정도는 된 것 같다. 

이제, 여기서 더 나아가 상태 바(Status Bar)의 표시 색상이 어두운 색이어야 할 것 같고, 북 리스트의 표시에 있어서 상단에 기본적으로 여백을 가지게 하여 그곳에 타이틀 바(Title Bar)를 표시해야 한다.


문제점 발생 ~~~~

  • 현재 Android SDK 19 부터 사용할 수 있도록 앱을 만들고 있는데 Status Bar 의 표시 색상은 무조건 밝은색 (흰색) 으로 표시된다.

  • Systembartint 같은 오픈소스도 있는데 이것도 Status Bar 의 배경만을 처리하는 것이며 표시 아이콘 색상은 SDK 21 부터 임의로 바꿀 수 있는것 같다.

  • 방법은 SDK 버전별로 Status Bar 표시 방식을 다르게 하는것이 좋을 듯 싶다.

  • 우선 SDK 21 이하에서는 Status Bar 의 배경색을 조금 어둡게 한다. 투명도는 적당히 주어 북 리스트가 위로 스크롤 될 때 아래로 지나가는 느낌을 갖도록 한다.


그렇다면 안드로이드의 실행 코드에서 현재 장치가 SDK 버전 몇을 지원하고 있는지 알아야 할 것이다.


android.os.Build.VERSION.SDK_INT 가 SDK 버전을 뜻하는데 Build.VERSION_CODES 의 상수들과 비교가 가능하다.

예를 들어 기기의 SDK 버전이 FROYO 이하를 알아내기 위한 코드는 다음과 같다.

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) {
	... 
}


코드에 다음과 같은 확인 코드를 넣고 각 안드로이드 버전의 장치 마다 실행시켜보면 표시되는 값이 다르게 나올 것이다.

System.out.println(">>>>>> SDK " + Build.VERSION.SDK_INT);

장치가 Android Version 4.4.4 인 경우 다음과 같은 내용이 출력된다.

10-15 17:32:15.877: I/System.out(16034): >>>>>> SDK 19

장치가 Android Version 6.0 인 경우 다음과 같은 내용이 출력된다.

10-15 17:34:40.653: I/System.out(2486): >>>>>> SDK 23



이러한 특성을 가지고 다음과 같은 코드를 작성하였다.
super.onCreate(savedInstanceState);

// 상단 status bar 의 생상을 어두운 색상으로 하기 위해 (주의 : API 24 이상에서 부터 사용됨)
boolean shouldChangeStatusBarTintToDark = true;

requestWindowFeature(Window.FEATURE_NO_TITLE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

View rootView = getWindow().getDecorView();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
if (shouldChangeStatusBarTintToDark)
{
// 상태바의 아이콘 생각을 어두운 색으로 사용
rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
else
{
// 상태바의 아이콘 색상을 밝은 색으로 사용
rootView.setSystemUiVisibility(0);
}
}
else
{
shouldChangeStatusBarTintToDark = false;
}


setContentView(R.layout.book_list_activity);

코드를 적용하여 각 안드로이드 버전별 출력되는 화면은 다음과 같다.

API 19   API 22  API 24

위의 그림과 같은 화면에서 알 수 있듯이 안드로이드 API 버전별로 크게 3 가지 특징을 가진다.

  • API 19 ~ :  상단 Status Bar 의 색상을 투명하게 할 수 있지만 약간의 어두운 그라데이션을 가지게 된다.

  • API 22 ~ : 상단 Status Bar 의 색상을 완전 투명하게 할 수 있지만 표시되는 내용은 흰색으로 표시되게 된다.

  • API 24 ~ : 상단 Status Bar 의 색상을 완전 투명하게 할 수 있고 표시되는 내용을 어두운 색상으로 표시 할 수 있게 된다.


이제 우리는 화면의 상단에 반투명의 타이틀바를 추가하여 상태바 (Status Bar) 와 잘 어울리도록 코드를 추가하고 수정 할 수 있게 되었다.

레이아웃 xml 에 다음과 같이 타이틀바를 적당한 위치에 추가하였다.

mBookListTitleView 라는 사각 형태가 상단에 반투명으로 자리할 것이며 그 안에 mBookListTitle 이라는 TextView 로 하여금 타이틀이 표시되게 된다.

<RelativeLayout
android:id="@+id/mBookListTitleView"
android:layout_width="match_parent"
android:layout_height="50dp">
<TextView
android:id="@+id/mBookListTitle"
android:gravity="center"
android:layout_width="match_parent"
android:textSize="16sp"
android:textColor="@color/dark_grey_font"
android:layout_height="50dp"
android:layout_marginTop="15dp" />
</RelativeLayout>

레이아웃에 위의 내용을 추가하고 코드에 다음과 같은 내용을 추가한다.

mBookListTitleView = (RelativeLayout) findViewById(R.id.mBookListTitleView);
mBookListTitle = (TextView) findViewById(R.id.mBookListTitle);

if(shouldChangeStatusBarTintToDark)
{
mBookListTitleView.setBackgroundColor(0x55FFFFFF);
mBookListTitle.setTextColor(0xFF444444);
}
else
{
mBookListTitleView.setBackgroundColor(0x77AAAAAA);
mBookListTitle.setTextColor(0xFF222222);
}

mBookListTitle.setText(R.string.albumbook_local);

shouldChangeStatusBarTintToDark 라는 변수는 이전에 작성한 코드에서 알수 있듯이 API 24 이상에서 true 를 가지게 된다. 즉, 이 변수는 API 레벨 24 이상에서만 true 를 가지며 그 아래의 API 버전과 표시되는 색상의 차별화를 가질 수 있도록 한다.

다음은 위의 코드를 적용시킨 후의 표시 화면이다. 역시 API 19, 22, 24 의 버전별 화면을 캡춰하였다.

API 19   API 22   API 24

API 24 이상의 경우를 제외한 이 미만의 API 버전 (예를 들어 API 19, API 22) 의 경우 표시되는 색상에 대하여 더 고민해야 할 듯 하다.

여기서는 각 API 버전별로 색상 등을 따로 처리하는 코드를 익히는데 목적을 두기 때문에 이 상태에서 계속 진행을 하도록 한다.


타이틀바 (주의 : 여기서의 타이틀바는 안드로이드 테마에서 제공하는 타이틀바가 아님. 앞쪽의 레이아웃 xml 에서 우리가 직접 Relative Layout 과 Text View 를 이용하여 생성한 타이틀바임.) 의 아래에 그리드뷰가 침범을 하여 표시되는 북 아이콘들이 타이틀바와 겹쳐지는 것을 수정하지 않으면 안될 것이다.

그리드뷰(Grid View)를 윗쪽 방향으로 스크롤하여 겹쳐지는것 (그리드뷰의 아이콘들이 반투명으로 표시되는 타이틀바 상태바의 아래로 표시되는 것) 은 정상이지만, 화면의 초기값 (그리드뷰가 가장 상단의 내용을 표시하는, 옵셋값이 0 일때) 에서는 기본적으로 그리드뷰의 북 아이콘이 타이틀바와 겹쳐지지 않아야 된다.


화면을 구성하는 Grid View 의 속성에서 paddingTop, clipToPadding 값을 다음과 같이 설정한다. paddingTop 의 값은 화면 상단의 상태바 및 타이틀바의 높이 만큼 입력하면 알맞을 듯 싶다.

clipToPadding 값을 false 로 설정하지 않으면 그리드뷰의 상단의 padding 값이 그리드뷰의 상단 스크롤 여백으로 되어서 윗쪽으로 스크롤 될 때 타이틀바 및 상태바 밑으로 그리드뷰 아이콘들이 밀고 들어가지 않게 된다. 그것은 우리가 바라는것이 아니다. clipToPadding 값을 false 로 설정하여 아이콘들이 padding 값에 의해서 클리핑 되지 않도록 한다.

<GridView
android:id="@+id/mBookListGridView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:numColumns="2"
  android:paddingTop="50dp"
   android:clipToPadding="false"> </GridView>

다음은 이 글을 작성하는데 목적을 두고 있는 상단 상태바 (Status Bar) 표시 및 투명처리의 각 안드로이드 버전별 결과 화면이다.

API 19  API 22  API 24


이 글은 안드로이드용 앱을 만들때 상단의 상태바 및 타이틀 바를 (반)투명하게 표시하고 앱에 의해서 표시되는 컨텐츠가 상태바 및 타이틀바의 밑으로 밀고 들어가는 방법을 구현하는데 도움이 되기위해 작성되었다. 비록 각자의 프로젝트와 딱 맞는 경우는 아니지만 상황을 분석하고 각 API 에 따른 프로그램의 적용에 도움이 되길 바라는 마음이다.


계속해서 그리드뷰의 아이콘을 아이폰 앱처럼 변경 할 것이며, 그리드뷰에 북 받침대를 표시하는 방법에 대하여 설명할 예정이다. 관심이 있는 안드로이드 개발자분들이 참조하시면 좋을 듯 싶다.


반응형
Comments