ANDROID 프로그래밍/APPBAR

안드로이드 툴바 기본 사용법. (Android Toolbar)

뽀따 2019. 1. 26. 13:17


1. 안드로이드 툴바(Toolbar)와 앱바(App Bar)

툴바(Toolbar)는 안드로이드 5.0 (API Level 21)부터 추가된 위젯(Widget)으로, 앱에서 가장 중요한 액션 또는 가장 자주 사용되는 액션들을 제공하는 앱바(AppBar)를 만들 때 사용합니다.


[안드로이드 액션바 기본 사용법]에서 설명했듯이, 예전에는 앱바(App Bar)가 ActionBar 클래스를 사용하여 만들어졌습니다. 그래서 앱바(App Bar)를 액션바(ActionBar)라고 부르기도 하며, 아직까지 많은 곳에서 앱바와 액션바, 이 두 가지 용어를 혼용해서 사용합니다.


그런데 새로운 버전의 안드로이드가 릴리즈됨에 따라, 액션바에도 다양한 기능들이 추가되고 표시 형태 또한 변화되었습니다. 그리고 이런 변화로 인해, 기기에 설치된 안드로이드 버전에 따라 액션바가 다르게 동작하는 결과를 낳게 되었죠. 동일한 액션바를 사용해도 버전에 따라 다른 동작을 수행한다는 것은, 개발자와 사용자 모두에게 불합리함으로 여겨질 수 밖에 없는 큰 단점입니다.


자, 그럼 당연히 구글에서는 이러한 단점을 보완할 수 있는 방법을 마련했겠지요? 버전에 따라 동작이 달라지는 파편화(Fragmentation) 문제를 해결하고 하위 호환성(Backward Compatibility)을 제공하기 위한 방법, 바로 지원 라이브러리(Support Library)를 사용하는 것입니다.


그래서 최근에 추가되는 앱바(App Bar)의 여러 기능들은 v7 AppCompat 지원 라이브러리Toolbar 위젯으로 구현되고 있습니다. 그리고 당연히, 앞서 언급한 하위 호환성(Backward Compatibility)을 확보하기 위해서는 v7 AppCompat 지원 라이브러리의 툴바를 사용하여 앱바(App Bar)를 구현해야 합니다.


결론적으로, v7 AppCompat 지원 라이브러리의 툴바(android.support.v7.widget.Toolbar)를 사용하여 앱바(App Bar)를 만들면, 많은 종류의 기기에서 일관된 앱바(App Bar)의 동작을 확보할 수 있습니다.

1.1 액션바(ActionBar) vs 툴바(Toolbar)

앞선 글, [안드로이드 액션바 기본 사용법]에서 액션바 위젯을 사용하여 앱바(App Bar)를 다루는 방법에 대해 설명하였는데요, 그렇다면 액션바를 사용하는 것과 툴바를 사용하는 것은 어떤 차이가 있을까요?


먼저, 앞서 설명했듯이 안드로이드 버전에 따라 다르게 동작하는 액션바와 다르게, 툴바는 하위 호환성(Backward Compatilibity)을 제공함으로 많은 버전에서 일관되게 동작합니다. 그래서 버전에 따른 기능 동작 여부를 신경써서 구현할 필요가 없죠.


그리고 액션바는 액티비티 내부에 기본적으로 포함된 요소입니다. 그러므로 액티비티의 레이아웃 XML에 액션바 위젯을 추가하지 않아도 액티비티에 지정된 테마가 앱바(App Bar)를 지원하면, 액션바를 액티비티의 앱바(App Bar)로 사용할 수 있습니다.


하지만 툴바는 액티비티의 레이아웃 XML에 작성되는 여느 다른 뷰(View) 위젯들과 다르게 취급되지 않습니다. 그래서 툴바를 사용하려면 액티비티의 레이아웃 XML에 android.support.v7.widget.Toolbar를 추가한 다음, 액티비티에 ".NoActionBar"가 포함된 테마를 지정하여 기본 액션바가 사용되지 않게 만들어야 합니다. 그리고 마지막으로 액티비티의 setSupportActionBar() 메서드를 호출하면 툴바를 액티비티의 앱바(App Bar)로 사용할 수 있습니다.


액티비티에서 툴바가 일반적인 뷰(View) 위젯으로 다루어진다는 것은 액티비티에 포함된 액션바에 비해 몇 가지 장점을 가지는데, 스타일 변경, 위치 조절, 애니메이션, 그리고 표시 형태 제어 등을 좀 더 손 쉽게 수행할 수 있다는 것입니다.


그리고 액티비티의 고정된 위치에 단 하나만 표시할 수 있는 액션바와 달리, 툴바는 각각 분리된 영역에 여러 개를 사용할 수 있습니다.

2. 툴바(Toolbar)를 앱바(App Bar)로 사용하기 위한 절차.

액티비티의 테마 설정만으로 사용 여부를 결정할 수 있는 액션바와 달리, 툴바를 사용하려면 몇 가지 설정 과정이 필요합니다. 일단, 툴바는 액티비티의 입장에서 일반적인 뷰(View)로 취급되니까요.

2.1 Toolbar 위젯에 대한 Dependency 추가.

v7 AppCompat 지원 라이브러리의 툴바를 사용하기 위해서는, 당연히, 프로젝트에 v7 AppCompat 지원 라이브러리에 대한 Dependency가 포함되어야 합니다. 아래 소스의 내용과 같이, "build.gradle (Module:app)" 파일에 "com.android.support:appcompat-v7:xx.x.x"를 추가하면 됩니다.

"build.gradle" - v7 AppCompat 지원 라이브러리 Dependency 추가.
dependencies {
    implementation 'com.android.support:appcompat-v7:27.1.1'
}

2.2 액티비티에 포함된 기본 ActionBar 사용하지 않게 만들기.

다음, 액티비티에서 기본으로 제공되는 ActionBar를 사용하지 않게 만들어야 합니다. 이를 위해서, 액티비티의 테마 설정에 ".NoActionBar"가 포함된 테마를 지정합니다.

"/res/values/styles.xml" - 기본 ActionBar 사용하지 않게 만들기.
<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        ...
    </style>
</resources>


2.3 액티비티의 레이아웃 XML에 Toolbar 위젯 추가.

이제 액티비티의 레이아웃에 Toolbar 위젯을 추가해야 합니다. 일반적인 뷰 위젯을 배치하듯, 액티비티 레이아웃 XML 파일의 앞 부분에 Toolbar 위젯을 추가하면 됩니다.

"/res/layout/activity_main.xml" - Toolbar 위젯 추가.
    <android.support.v7.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:id="@+id/app_toolbar"/>

2.4 Toolbar를 액티비티의 앱바(App Bar)로 지정.

마지막으로, 액티비티의 setSupportActionBar() 메서드를 통해 앞서 추가한 Toolbar를 액티비티의 앱바(App Bar)로 지정합니다.

"MainActivity.java" - Toolbar를 액티비티의 앱바(App Bar)로 지정.
    Toolbar tb = (Toolbar) findViewById(R.id.app_toolbar) ;
    setSupportActionBar(tb) ;

2.5 앱바(App Bar) 제어를 위해 툴바 액세스하기.

툴바를 액티비티의 레이아웃에 추가하고 setSupportActionBar() 메서드를 통해 액티비티의 앱바(App Bar)로 지정하고나면, 앱바(App Bar)의 여러 기능을 사용하기 위해 툴바에 대한 참조를 획득할 수 있습니다. 이 때, [안드로이드 액션바 기본 사용법 - 2.2 앱바(App Bar) 액세스하기]에서 살펴봤던 getSupportActionBar() 메서드를 사용합니다. 참고로, getSupportActionBar()의 리턴 타입이 Toolbar가 아닌, ActionBar인 것에 주의하세요.

"MainActivity.java" - Toolbar에 대한 참조 획득하기.
    ActionBar ab = getSupportActionBar() ;

    // TODO : use ab.

3. 툴바(Toolbar)를 사용하여 앱바(App Bar) 만들기

이제 예제를 통해 툴바를 사용하여 앱바를 만드는 방법에 대해 알아보도록 하겠습니다. 단계별로 코드를 하나씩 추가해가며 툴바 사용법에 대한 예제를 작성할텐데요. 그런데 아래 예제의 설명과 코드가 위에서 설명한 내용에 중복되는 부분이 많아 글을 읽는 것이 조금 지루하게 느껴질 수도 있습니다. 하지만 앱바를 처음 다뤄보는 개발자라면, 툴바 구성 절차의 전체적인 흐름을 파악하는데 좀 더 도움이 될 거라 생각합니다.


참고로, 본문에서 설명하는 내용이 잘 이해되지 않는다면, [안드로이드 액션바 기본 사용법]을 먼저 읽어보시는 게 조금은 더 도움되실거라 생각합니다.

3.1 v7 AppCompat 지원 라이브러리에 대한 설정 추가.

지원 라이브러리의 툴바(Toolbar) 클래스를 사용하여 액티비티의 앱바(App Bar)를 구현하기 위해서는 가장 먼저 툴바(Toolbar)가 포함된 지원 라이브러리를 프로젝트에 추가해야 합니다. 툴바(Toolbar) 클래스는 v7 AppCompat 지원 라이브러리에 포함되어 있으므로, "com.android.support:appcompat-v7:x.x.x"를 build.gradle 파일에 추가하면 됩니다.


그런데 안드로이드 스튜디오에서 프로젝트 생성 중 액티비티 선택 과정에서 "Backward Compatibility"를 체크했다면, v7 AppCompat 지원 라이브러리에 대한 설정이 자동으로 추가되므로, 아래의 설정이 제대로 추가되어 있는지만 확인하면 될 것 같습니다.


[STEP-1] "build.gradle" - v7 AppCompat 지원 라이브러리에 대한 설정 추가.
dependencies {
    ...
    implementation 'com.android.support:appcompat-v7:27.1.1'
    ...
}

3.2 액티비티의 기본 액션바(ActionBar)를 사용하지 않도록 테마 설정 변경.

[안드로이드 액션바 기본 사용법 - 액션바(ActionBar) 사용법]에서 설명했듯이, 안드로이드 3.0(API Level 11)부터, 기본 테마를 사용하는 모든 액티비티에서 ActionBar 클래스가 앱바(App Bar)로 사용됩니다. 하지만 여기서는 액티비티에서 제공되는 액션바(ActionBar)가 아닌, v7 AppCompat 지원 라이브러리의 툴바(Toolbar) 클래스를 사용하여 앱바(App Bar)를 만드는 방법을 설명하므로, 액티비티의 기본 액션바(Action)를 사용하지 않도록 만들어야 합니다.


[2.2 액티비티에 포함된 기본 ActionBar 사용하지 않게 만들기]에서 액션바를 사용하지 않는 방법에 대해 설명했습니다. 바로 이름에 "NoActionBar"가 포함된 테마를 앱의 테마로 지정하는 것입니다.

"AndroidManifest.xml" 파일 내용
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ppottasoft.toolbarexample">

    <application
        ...
        android:theme="@style/AppTheme">
        ...
    </application>
</manifest>
[STEP-2] "/res/values/styles.xml" - 앱 테마에 "NoActionBar" 테마 지정.
<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        ...
    </style>
</resources>

3.3 액티비티 레이아웃에 툴바(Toolbar) 추가.

이제 액티비티의 앱바(App Bar)로 사용할 툴바(Toolbar) 클래스를 액티비티의 레이아웃 XML에 추가합니다. 참고로 v7 AppCompat 지원 라이브러리의 툴바(Toolbar) 클래스의 전체 패키지 경로는 "android.support.v7.widget.Toolbar" 입니다. (툴바 아래의 텍스트뷰는 뒤에 나올 액션 메뉴 선택 시 텍스트를 표시하기 위해 추가하였습니다.)

[STEP-3] "activity_main.xml" - 액티비티의 레이아웃에 툴바(Toolbar) 추가.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.ppottasoft.toolbarexample.MainActivity">

    <android.support.v7.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:id="@+id/app_toolbar"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="48sp"
        android:gravity="center"
        android:id="@+id/textView"
        android:text="TEXT"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />

</android.support.constraint.ConstraintLayout>

3.4 툴바(Toolbar)를 액티비티의 앱바(App Bar)로 설정하기.

이제, 액티비티의 레이아웃에 추가한 툴바(Toolbar)를 액티비티의 앱바(App Bar)로 설정하는 코드를 작성해야 합니다. 이를 위해서는 액티비티의 onCreate() 메서드에서 setSupportActionBar() 메서드를 호출하면 됩니다. 아래의 코드에서 Toolbar 클래스를 사용하기 위해, v7 지원 라이브러리(android.support.v7.widget.Toolbar)의 Toolbar 클래스를 import한 것에 주의하세요.

[STEP-4] "MainActivity.java" - 툴바(Toolbar)를 액티비티의 앱바(App Bar)로 설정.
import android.support.v7.widget.Toolbar;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        
        // 코드 계속 ...

        Toolbar tb = (Toolbar) findViewById(R.id.app_toolbar) ;
        setSupportActionBar(tb) ;
    }
}

여기까지가, 기본 액션바(ActionBar) 대신 툴바(Toolbar)를 사용하여 앱바(App Bar)를 만드는 설정 과정입니다. 앱을 빌드하고 실행하면 아래와 같은 실행화면을 확인할 수 있습니다.


3.5 앱바(App Bar)에 액션 및 오버플로우 메뉴 추가하기.

액션 및 오버플로우 메뉴를 추가하는 과정은 [안드로이드 액션바 기본 사용법 - 2.4 앱바(App Bar)에 액션(Action) 추가하기]에서 액션바(ActionBar)를 사용하여 만든 방법과 동일합니다.


먼저 앱바(App Bar)의 액션에 표시될 이미지를 Drawable 리소스에 추가합니다.

[STEP-5.1] "/res/drawable/" - 액션에 아이콘으로 표시할 Drawable 리소스 추가.


다음, 앱바(App Bar)에 표시될 액션과 오버플로우 메뉴 아이템을 정의하기 위해 메뉴 리소스 XML을 추가해야 합니다. [안드로이드 액션바 기본 사용법 - 앱바(App Bar)에 액션(Action) 추가하기]에서 설명한대로, 메뉴 리소스 XML 파일은 "/res/menu/" 아래에 추가해야 하는데, 프로젝트에 따라 "/res/menu" 디렉토리가 미리 만들어져있지 않을 수도 있습니다. 이런 경우, "/res" 폴더에서 마우스 오른쪽 버튼을 클릭한 다음, New - Directory 메뉴를 선택하면 "/res/menu/" 디렉토리를 추가할 수 있습니다.


하지만 굳이 디렉토리를 별도로 추가하지 않아도, 메뉴 리소스 XML 파일을 추가할 수 있는 방법이 있습니다. 리소스 파일을 추가할 때 "Resource type"을 "Menu"로 지정하면, "/res/menu" 디렉토리를 생성함과 동시에 메뉴 리소스 XML 파일을 추가할 수 있습니다.

[STEP-5.2] "/res/menu/appbar_action.xml" - 메뉴 리소스 XML 파일 추가.


추가한 메뉴 리소스 XML 파일에는 아래와 같은 내용을 작성합니다. 메뉴 리소스 XML 각 아이템에 사용하는 항목, 특히 "showAsAction"에 대한 설명은 [안드로이드 액션바 기본 사용법 - 앱바(App Bar)에 액션(Action) 추가하기]에서 확인할 수 있습니다.

[STEP-5.3] "/res/menu/appbar_action.xml" - 앱바(App Bar) 액션을 위한 메뉴 리소스 XML 작성.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/action_search"
        android:icon="@drawable/ic_search_black_24dp"
        android:title="Search"
        app:showAsAction="always"/>

    <item
        android:id="@+id/action_account"
        android:icon="@drawable/ic_supervisor_account_black_24dp"
        android:title="Account"
        app:showAsAction="always"/>

    <item
        android:id="@+id/action_settings"
        android:title="Settings"
        app:showAsAction="never"/>
</menu>

이제, 앞서 작성한 메뉴 리소스 XML 파일이 앱바(App Bar)에 표시되도록 만들어야 합니다. 이를 위해서는, 액티비티의 onCreateOptionsMenu() 메서드에서 메뉴 리소스를 사용하도록 만들어야 합니다. 아래 코드와 같이, onCreateOptionsMenu()의 파라미터로 전달된 menu 변수에 앞서 작성한 메뉴 리소스를 inflate하면, 메뉴 리소스 XML의 내용을 앱바(App Bar)에 반영되도록 만들 수 있습니다.

[STEP-5.4] "MainActivity.java" - onCreateOptionsMenu() 메서드에서 메뉴 inflate.
public class MainActivity extends AppCompatActivity {

    // 코드 계속 ...

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.appbar_action, menu) ;

        return true ;
    }
}

3.6 앱바(App Bar)의 액션 및 오버플로우 메뉴 클릭 이벤트 처리하기.

앱바(App Bar)에 표시된 액션 또는 오버플로우 메뉴가 선택되면, 액티비티의 onOptionsItemSelected() 메서드가 호출됩니다. 그리고 onOptionsItemSelected() 메서드의 파라미터로 전달되는 MenuItem에는 선택된 액션 또는 오버플로우 메뉴의 정보가 들어 있습니다. 특히, MenuItemgetItemId() 메서드를 사용하면 메뉴 리소스 XML에서 작성한 아이템 id를 식별할 수 있습니다.

[STEP-6] "MainActivity.java" - onCreateOptionsMenu() 메서드에서 메뉴 inflate.
public class MainActivity extends AppCompatActivity {

    // 코드 계속 ...

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.action_search :
                ((TextView)findViewById(R.id.textView)).setText("SEARCH") ;
                return true ;
            case R.id.action_account :
                ((TextView)findViewById(R.id.textView)).setText("ACCOUNT") ;
                return true ;
            case R.id.action_settings :
                ((TextView)findViewById(R.id.textView)).setText("SETTINGS") ;
                return true ;
            default :
                return super.onOptionsItemSelected(item) ;
        }
    }
}

4. 실행 화면.

예제를 빌드하고 실행하면 아래와 같은 화면이 표시됩니다.


앱바의 각 액션 메뉴를 선택하면 아래 그림과 같이 화면 중앙의 텍스트뷰 텍스트가 변경되는 것을 확인할 수 있습니다.


5. 참고

.END.