Computer >> 컴퓨터 >  >> 프로그래밍 >> Android

Android 툴바 아이콘에 알림 개수(배지) 표시하는 방법

개요

이 예제는 Android 앱의 툴바(Toolbar) 아이콘 위에 알림 개수를 배지(Badge) 형태로 표시하는 방법을 다룹니다. 알림이 생성될 때마다 카운트가 하나씩 증가하며, 그 숫자가 툴바 우측 상단의 알림 아이콘 위에 작은 원형 배지로 나타나도록 구현합니다.

핵심 원리는 간단합니다. 툴바 내부에 알림 아이콘과 이를 덮는 TextView를 RelativeLayout으로 겹쳐 배치하고, 알림이 발생할 때마다 TextView의 텍스트 값을 갱신하는 것입니다.

1단계: 새 프로젝트 생성

Android Studio에서 File → New Project를 선택하여 새 프로젝트를 만듭니다. 프로젝트 생성에 필요한 세부 정보를 모두 입력한 뒤 진행하세요.

2단계: 레이아웃 파일 작성

res/layout/activity_main.xml 파일에 아래 코드를 추가합니다.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Toolbar
        android:layout_width="match_parent"
        android:layout_height="?actionBarSize"
        android:background="@color/colorPrimary">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginEnd="16dp">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:text="Notify Me"
                android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium"
                android:textColor="#FFF"
                android:textStyle="bold" />

            <!-- 알림 아이콘과 배지 영역 -->
            <RelativeLayout
                android:id="@+id/notificationBadge"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true"
                android:layout_centerVertical="true">

                <RelativeLayout
                    android:id="@+id/badgeLayout"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:paddingTop="8dp">

                    <Button
                        android:layout_width="36dp"
                        android:layout_height="36dp"
                        android:background="@drawable/action_notification" />
                </RelativeLayout>

                <!-- 아이콘 위에 겹쳐 표시되는 알림 개수 배지 -->
                <TextView
                    android:id="@+id/tvBadgeNumber"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignTop="@+id/badgeLayout"
                    android:layout_alignEnd="@id/badgeLayout"
                    android:background="@drawable/item_count"
                    android:text="0"
                    android:textColor="#FFF"
                    android:textSize="16sp"
                    android:textStyle="bold" />
            </RelativeLayout>
        </RelativeLayout>
    </Toolbar>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_margin="16dp"
        android:onClick="createNotification"
        android:text="create notification" />
</RelativeLayout>

여기서 tvBadgeNumber TextView가 핵심 요소입니다. layout_alignToplayout_alignEnd 속성을 사용해 알림 아이콘의 오른쪽 위 모서리에 배지를 겹쳐 배치합니다.

3단계: MainActivity 코드 작성

src/MainActivity.java 파일에 아래 코드를 추가합니다.

package app.tutorialspoint.com.notifyme;

import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

   public static final String NOTIFICATION_CHANNEL_ID = "10001";
   private final static String default_notification_channel_id = "default";
   static int notificationCount = 0;
   TextView tvBadgeNumber;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      tvBadgeNumber = findViewById(R.id.tvBadgeNumber);
   }

   public void createNotification(View view) {
      Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class);
      notificationIntent.putExtra("fromNotification", true);
      notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
      PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

      NotificationManager mNotificationManager =
              (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

      NotificationCompat.Builder mBuilder =
              new NotificationCompat.Builder(MainActivity.this, default_notification_channel_id);
      mBuilder.setContentTitle("My Notification");
      mBuilder.setContentIntent(pendingIntent);
      mBuilder.setContentText("Notification Listener Service Example");
      mBuilder.setTicker("Notification Listener Service Example");
      mBuilder.setSmallIcon(R.drawable.ic_launcher_foreground);
      mBuilder.setAutoCancel(true);

      // Android 8.0(Oreo) 이상에서는 알림 채널 생성 필수
      if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
         int importance = NotificationManager.IMPORTANCE_HIGH;
         NotificationChannel notificationChannel = new NotificationChannel(
                 NOTIFICATION_CHANNEL_ID, "NOTIFICATION_CHANNEL_NAME", importance);
         mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
         assert mNotificationManager != null;
         mNotificationManager.createNotificationChannel(notificationChannel);
      }

      assert mNotificationManager != null;
      mNotificationManager.notify((int) System.currentTimeMillis(), mBuilder.build());

      // 알림 개수 증가 후 배지 텍스트 갱신
      notificationCount++;
      tvBadgeNumber.setText(String.valueOf(notificationCount));
   }
}

버튼을 클릭하면 createNotification() 메서드가 호출되어 새 알림을 게시하고, 정적 변수 notificationCount를 1 증가시킨 뒤 그 값을 배지 TextView에 반영합니다.

4단계: 배지 배경 드로어블 작성

res/drawable/item_count.xml 파일을 만들고 아래 코드를 추가합니다. 이 드로어블은 배지의 파란색 원형 배경 역할을 합니다.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="https://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="8dp" />
    <solid android:color="#2196F3" />
    <stroke
        android:width="1dip"
        android:color="#FFF" />
    <padding
        android:bottom="2dp"
        android:left="2dp"
        android:right="2dp"
        android:top="2dp" />
</shape>

참고로 툴바의 알림 아이콘(@drawable/action_notification)은 벡터 드로어블 등 별도의 이미지 리소스로 미리 준비해 두어야 합니다.

5단계: AndroidManifest.xml 설정

AndroidManifest.xml 파일에 아래 코드를 추가합니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="app.tutorialspoint.com.notifyme">

    <uses-permission android:name="android.permission.VIBRATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

앱 실행 및 결과 확인

이제 앱을 실행해 결과를 확인해 보겠습니다. 실제 Android 기기가 컴퓨터에 연결되어 있다고 가정합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤 툴바의 Run 아이콘을 클릭하세요. 기기 선택 목록에서 사용 중인 모바일 기기를 고르면 앱이 설치되어 실행되고, 기본 화면이 표시됩니다.

화면 중앙의 create notification 버튼을 누를 때마다 새 알림이 생성되고, 툴바 우측 상단 알림 아이콘 위의 배지 숫자가 1씩 증가하는 것을 확인할 수 있습니다.