읽기 전

  • 불필요한 코드나 잘못 작성된 내용에 대한 지적은 언제나 환영합니다.
  • 개인적으로 사용해보면서 배운 점을 정리한 글입니다.

사이드 프로젝트에서 커뮤니티 기능을 구현하자는 의견이 나왔다. 커뮤니티 기능은 사실 제대로 구현하려면 거의 준 프로젝트 급이라 따로 페이지를 만들어서 구현하는게 낫겠다는 판단이 섰다. 시연용 앱만 제작하라고 주문받았지만 원래 관심이 있었던 분야라 기능적 구현 완성을 목표로 정리를 시작하려 한다.

이번 포스팅은 사용자가 원하는 형식으로 동작하는 Custom Toolbar 적용에 대한 내용입니다.

사전 작업

AppTheme 변경하기

Android Manifest.xml을 보면 Application 태그의 theme 속성에 android:theme="@style/AppTheme" 이런 식으로 AppTheme이 적용되어 있는 것을 볼 수 있다. 그리고 styles.xml의 AppTheme을 보면 ActionBar를 사용하도록 작성되어 있는데 <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">로 변경해주면 기본적으로 ActionBar가 비활성화된 상태로 액티비티가 실행된다. 이 작업은 앱 전체에 적용하는 과정으로 기본적으로 Toolbar가 삽입된 상태이고 특정 액티비티에서만 제거하고 싶다면 따로 Style을 정의 후 해당 액티비티 태그에 Theme을 적용하면 되겠다.

UI 배치하기

Toolbar View 배치

<androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/toolbar_layout"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/communityToolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="?attr/colorPrimary"
            android:minHeight="?attr/actionBarSize"
            android:theme="?attr/actionBarTheme"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:navigationIcon="@drawable/abc_vector_test">

            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/colorPrimary"
                android:orientation="horizontal">

                <androidx.constraintlayout.widget.Guideline
                    android:id="@+id/toolbar_hg_10"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal"
                    app:layout_constraintGuide_percent="0.15" />

                <androidx.constraintlayout.widget.Guideline
                    android:id="@+id/toolbar_hg_90"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal"
                    app:layout_constraintGuide_percent="0.85" />

                <TextView
                    android:id="@+id/toolBarTitle"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="커뮤니티"
                    android:textColor="#FFFFFF"
                    android:textSize="18sp"
                    android:textStyle="bold"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

            </androidx.constraintlayout.widget.ConstraintLayout>
        </androidx.appcompat.widget.Toolbar>
    </androidx.constraintlayout.widget.ConstraintLayout>

커스텀 툴바를 적용하기 위해 layout 파일에 다음과 같이 정의하였다. 툴바에서의 back 버튼은 navigation icon 지정을 통해 만들 수 있다. 그리고 app title이 아니라 별도의 액티비티 타이틀을 적용하려 하므로 적당히 textView를 내부에 종속되게끔 적용한 뒤 크기 비율을 guideline으로 맞춰줬다.

menu 리소스 폴더, layout 파일 생성

커스텀 툴바에 원하는 버튼 기능을 우측에 별도로 삽입하고 싶다. 이 경우 menu resouce type을 갖는 resource 폴더를 생성해야 한다. res 폴더에 새로운 폴더를 생성하면서 [New] - [Android Resource Directory]를 클릭하면 특정 리소트 타입을 갖는 폴더 생성이 가능하다. Resource Type을 menu로 지정하고 폴더를 생성한다.

Android_Custom_Toolbar_01

폴더를 생성한 뒤 커스텀 툴바 형식을 지정하기 위한 layout을 생성한다. Menu Item을 넣으면 우측에 리스트로 표시된다. 이걸 항상 표시하게끔 전환하고 원하는 이미지를 삽입해서 버튼처럼 보여주자.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/btnCommunityNotification"
        android:icon="@drawable/notification_icon"
        android:title="notification"
        app:showAsAction="always" />
    <item
        android:id="@+id/btnCommunitySearch"
        android:icon="@drawable/search_icon"
        android:title="app_bar_search"
        app:showAsAction="always" />
</menu>

프로젝트 기능 상 커뮤니티 메인에서는 유저 알림과 포스트 검색 기능을 넣으려 한다. 각각 버튼에 대해 클릭 시 별도의 액티비티를 띄울 예정이므로 단순 item을 넣어주었다. 만약 현재 액티비티에서 구체적인 동작을 원하면 Search Item 등을 넣어서 구성하면 되겠다.

코드 작업하기

UI는 끝났으니 이제 코드로 커스텀 툴바를 입혀줘야 한다. 코드가 조금 필요하므로 별도의 메소드를 생성해서 보여주기로 했다.

Toolbar 정의하기

    private void initView() {
        Toolbar communityToolbar = findViewById(R.id.communityToolbar);
        setSupportActionBar(communityToolbar);
        ActionBar actionBar = getSupportActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);
        communityToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                goToMainActivity();
            }
        });
    }

툴바를 정의하는 코드다. 먼저 액티비티에 툴바를 정의한 뒤 액티비티 layout에서 id를 찾아 지정해준다. 그리고 setSupportActionBar()메소드로 해당 툴바를 사용하겠다고 선언한 뒤 ActionBar를 정의한다.

ActionBar는 Toolbar의 하위버전으로 Toolbar가 ActionBar의 버전 별 동작이 파편화되는 점을 방지하고자 도입되었다.

setDisplayHomeAsUpEnabled(Boolean)은 Boolean 값에 따라 Toolbar에 뒤로가기 버튼 생성 여부를 결정한다. 그리고 layout에 정의했듯이 navigation 버튼 속성이 적용된다. 뒤로가기 버튼 정의를 하였으니 진짜 뒤로 가게끔 클릭 리스너와 Intent를 정의하여 실행하면 된다.

커스텀 툴바 적용하기

방금까지는 기본적인 툴바를 정의했다면 이제 별도의 layout을 생성하여 item을 지정한 커스텀 툴바를 적용해야 한다. 내부 메소드이므로 @Override 속성을 갖게끔 정의해야 한다.

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater menuInflater = getMenuInflater();
    menuInflater.inflate(R.menu.community_tool_bar, menu);
    return true;
}

MenuInflater를 정의해서 menu 리소스 폴더에 생성해두었던 커스텀 툴바 layout을 infalte시킨다.

버튼 클릭 리스너 정의하기

커스텀 layout에는 개인적으로 정의해뒀던 menu item들이 있고 버튼처럼 동작하게끔 만들고 싶다. 해당 동작에 대응되는 메소드도 정의해주자.

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.btnCommunityNotification:
                Toast.makeText(getApplicationContext(), "알림버튼클릭", Toast.LENGTH_SHORT).show();
                return true;
            case R.id.btnCommunitySearch:
                Toast.makeText(getApplicationContext(), "검색버튼클릭", Toast.LENGTH_SHORT).show();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

역시 @Override 속성을 받아 내부 메소드로 구현한다. 어떤 MenuItem이 선택되었는지 id값에 따라 동작을 달리하게끔 만들어주면 되겠다.

동작 결과

Android_Custom_Toolbar_02

+ Recent posts