Building Actionbar notifications count Icon

    In some app like Google, we see number of new notifications is shown in ActionBar like this:
It's so intutive for users and convenient for actions. In this sample post, I will present the simple way to make an application which has similar UI like above.

1. Start Android Studio and create a new project (min sdk I used is 14).
2. Create an Activity which sending information (ForwardActivity)

    In this Activity, we will send data to NotificationActivity based on CheckBoxes check/unchecked. It's layout (declaring in xml file):
activity_notification.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_margin="10dp"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:textSize="22sp"
        android:text="@string/choose"
        android:textColor="@android:color/holo_green_dark"
        android:layout_margin="10dp"
        android:layout_height="wrap_content" />

    <CheckBox
        android:id="@+id/chk_android"
        android:text="@string/android"
        android:textColor="#003399"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <CheckBox
        android:textColor="#003399"
        android:id="@+id/chk_ios"
        android:text="@string/ios"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <CheckBox
        android:textColor="#003399"
        android:id="@+id/chk_wp"
        android:text="@string/wp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <CheckBox
        android:textColor="#003399"
        android:id="@+id/chk_other"
        android:text="@string/other"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/btn_go"
        android:text="@string/go"
        android:layout_margin="10dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>
    Programmatically code: sending data (List of Strings) after click the Button:

private View.OnClickListener onClickListener() {
        return new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                isChecked(chkAndroid, "Android");
                isChecked(chkIOS, "IOS");
                isChecked(chkWP, "Window Phone");
                isChecked(chkOther, "Other Mobile Platform");

                //go to activity and put string array
                Intent intent = new Intent(ForwardActivity.this, NotificationActivity.class);
                intent.putStringArrayListExtra("notification", intentStrings);
                startActivity(intent);
                intentStrings.clear();
            }
        };
    }

    /**
     * Append String when checkbox checked
     * @param checkBox
     * @param s
     */
    private void isChecked(CheckBox checkBox, String s) {
        if (checkBox.isChecked()) {
            intentStrings.add(s);
        }
    }

3. Create an activity which show notifications

- Firstly, create a menu_notification.xml in res/menu folder:
menu_notification.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="com.blogspot.hongthaiit.notification.NotificationActivity">

    <item
        android:id="@+id/badge"
        android:actionLayout="@layout/feed_update_count"
        android:icon="@drawable/shape_notification"
        android:showAsAction="always">
    </item>
</menu>
- Action layout (feed_update_count.xml) in res/layout folder for this menu:
feed_update_count.xml
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/notif_count"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:minWidth="32dp"
    android:minHeight="32dp"
    android:background="@drawable/shape_notification"
    android:text="0"
    android:textSize="16sp"
    android:textColor="@android:color/white"
    android:gravity="center"
    android:padding="5dp"
    android:singleLine="true">

    </Button>
- Layout for this Activity: a TextView to show notification content:
activity_notification.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/notifi_text"
        android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_centerInParent="true"
        android:textSize="22sp"
        android:textColor="#990000"
        android:layout_margin="10dp"
        android:gravity="center"
        android:layout_height="wrap_content" />

</RelativeLayout>
    In code, inflating menu in onCreateOptionsMenu() method, open NotificationActivity and paste this code:
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_notification, menu);

        View count = menu.findItem(R.id.badge).getActionView();
        btnNotifCount = (Button) count.findViewById(R.id.notif_count);
        btnNotifCount.setText(String.valueOf(intentList.size()));

        //show list of notifications when menu button clicked
        btnNotifCount.setOnClickListener(onClickListener());

        return super.onCreateOptionsMenu(menu);
    }
    Handle click event of badge icon method (show a PopupMenu):
private View.OnClickListener onClickListener() {
        return new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Creating the instance of PopupMenu
                PopupMenu popup = new PopupMenu(NotificationActivity.this, btnNotifCount);
                //Inflating the Popup using xml file
                popup.getMenuInflater()
                        .inflate(R.menu.menu_popup, popup.getMenu());

                createPopupMenuItems(popup);
                popup.show();
            }
        };
    }

    private void createPopupMenuItems(final PopupMenu popup) {
        if (intentList.size() > 0) {
            for (int i = 0; i < intentList.size(); i++) {
                popup.getMenu().add(intentList.get(i));
            }

            popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {

                    textView.setText("You selected " + item.getTitle() + " at MainActivity");
                    intentList.remove(item.getTitle()); //remove notification after clicked (read)
                    setBtnNotifCount(intentList.size()); //update notifications count
                    popup.dismiss();

                    return true;
                }
            });
        }
    }
    Add some important methods, we have full NotificationActivity code:
NotificationActivity.java
package com.blogspot.hongthaiit.notification;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.PopupMenu;
import android.widget.TextView;

import java.util.ArrayList;


public class NotificationActivity extends Activity {

    private Button btnNotifCount;
    private TextView textView;
    private int mNotifCount = 0;
    private ArrayList<String> intentList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notification);
        textView = (TextView) findViewById(R.id.notifi_text);

        getDataFromIntent();
    }

    private void getDataFromIntent() {
        intentList = getIntent().getStringArrayListExtra("notification");
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_notification, menu);

        View count = menu.findItem(R.id.badge).getActionView();
        btnNotifCount = (Button) count.findViewById(R.id.notif_count);
        btnNotifCount.setText(String.valueOf(intentList.size()));

        //show list of notifications when menu button clicked
        btnNotifCount.setOnClickListener(onClickListener());

        return super.onCreateOptionsMenu(menu);
    }

    private void setBtnNotifCount(int count){
        mNotifCount = count;
        invalidateOptionsMenu();
    }

    private View.OnClickListener onClickListener() {
        return new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //Creating the instance of PopupMenu
                PopupMenu popup = new PopupMenu(NotificationActivity.this, btnNotifCount);
                //Inflating the Popup using xml file
                popup.getMenuInflater()
                        .inflate(R.menu.menu_popup, popup.getMenu());

                createPopupMenuItems(popup);
                popup.show();
            }
        };
    }

    private void createPopupMenuItems(final PopupMenu popup) {
        if (intentList.size() > 0) {
            for (int i = 0; i < intentList.size(); i++) {
                popup.getMenu().add(intentList.get(i));
            }

            popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
                @Override
                public boolean onMenuItemClick(MenuItem item) {

                    textView.setText("You selected " + item.getTitle() + " at MainActivity");
                    intentList.remove(item.getTitle()); //remove notification after clicked (read)
                    setBtnNotifCount(intentList.size()); //update notifications count
                    popup.dismiss();

                    return true;
                }
            });
        }
    }
}

4. Some necessary files

- Shaping notification corner icon for make it better looking (res/drawable/shape_notification.xml):
shape_notification.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <stroke android:color="#22000000" android:width="2dp" />
    <corners android:radius="5dp" />
    <solid android:color="#CC0001" />
</shape>
- Strings resource:
strings.xml
<resources>
    <string name="app_name">Notification ActionBar</string>
    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>
    <string name="android">Android</string>
    <string name="ios">iOS</string>
    <string name="go">Go to Notification Activity</string>
    <string name="choose">Please choose a mobile platform</string>
    <string name="wp">Window Phone</string>
    <string name="other">Other platform</string>
    <string name="note">Note</string>
    <string name="title_activity_notification">NotificationActivity</string>
</resources>

5. Running application, we see our result like this



(Sorry for ads)

Share


Previous post
« Prev Post
Next post
Next Post »