Android

AndroidでActionbarのiconにバッジを付ける実装

More than 3 years have passed since last update.

AndroidでiPhoneのような未読件数表示用のバッジを実装しました。

下記のようなLibraryもあったのですが、layoutのxmlの読み込みがうまく行かなかったので自分で実装。

https://github.com/mikepenz/Android-ActionItemBadge


用意するファイル

必要なファイルは下記の3つのxmlと、メニューを表示させるActivityです。


  • res/menu/menu_hoge.xml(メニュー)

  • res/layout/hoge_icon.xml(上記のメニューのアイテムにバッジを付けた時のlayout)

  • res/drawable/shape_badge.xml(バッジのデザイン用のxml)

  • MainActivity.java

※コメントは説明用


menu_hoge.xml

<menu 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"
tools:context=".MainActivity">

<item android:id="@+id/action_hoge" android:title="Hoge"
android:icon="@android:drawable/ic_menu_info_details"
// layoutを指定
android:actionLayout="@layout/hoge_icon"
app:showAsAction="always" />
</menu>



hoge_icon.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="center"
android:layout_gravity="center"
android:clickable="true"
style="@android:style/Widget.ActionButton">

<ImageView
android:id="@+id/ic_hoge"
// menuのitemで指定したiconと同じものを指定
android:src="@android:drawable/ic_menu_info_details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_margin="0dp"
/>

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/hoge_count"
android:layout_width="wrap_content"
android:minWidth="17sp"
android:textSize="12sp"
android:textColor="@android:color/white"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@null"
// バッジの位置・サイズ調整
android:layout_alignTop="@id/ic_hoge"
android:layout_alignRight="@id/hoge_count"
android:layout_marginLeft="15dp"
android:layout_marginTop="3dp"
android:paddingBottom="1dp"
android:paddingRight="4dp"
android:paddingLeft="4dp"
// ここでバッジの背景を設定
android:background="@drawable/shape_badge"/>
</RelativeLayout>



shape_badge.xml

<?xml version="1.0" encoding="utf-8"?>

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="ring"
android:useLevel="false"
android:thickness="9dp"
android:innerRadius="0dp">
<solid
android:color="@android:color/holo_red_light"/>
<stroke
android:width="1dip"
android:color="@android:color/white"/>
<padding
android:top="2dp"
android:bottom="2dp"/>
</shape>


MainActivity.java

public boolean onCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.menu_hoge, menu);
// お知らせ未読件数バッジ表示
MenuItem item = menu.findItem(R.id.action_hoge);
MenuItemCompat.setActionView(item, R.layout.hoge_icon);
View view = MenuItemCompat.getActionView(item);
final TextView hogeCountLabel = (TextView)view.findViewById(R.id.hoge_count);

// バッジの数字を更新。0の場合はバッジを表示させない
// _unreadHogeCountはAPIなどで通信した結果を格納する想定です
if (_unreadHoge == 0) {
hogeCountLabel.setVisibility(View.INVISIBLE);
} else {
hogeCountLabel.setText(String.valueOf(_unreadHogeCount));
}
...



注意点