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));
}
...
注意点
- AppCompatのバージョンによって、setActionViewが不要なようです。今回はv7を想定
- 通信後にバッジを更新する場合は、通信成功後にsupportInvalidateOptionsMenu()などでmenuを更新する必要があります。
- 参考にした記事
http://stackoverflow.com/questions/17696486/actionbar-notification-count-icon-like-google-have