Notification count Badge in Android
In this tutorial we will learn how to make a round notification count Badge. For ex: If a notification is received or item is added the count is increased and decreased with a round shape in the Action bar in Android Apps.
Example:
- Create a new project as Badge, in Android Studio and do as follows step by step.
- Do the following in activity_main.xml file.
<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" tools:context="com.example.hss_24.badge.MainActivity"> <TextView android:text="Android Lovers" android:textSize="30sp" android:textStyle="bold" android:gravity="center" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" /> </RelativeLayout>
- Create a new package in your project, Right click on app-->new-->package-->res-->name it as menu.
- Create a new xml in menu directory and name it as menu_home.xml.
- Copy paste the following in menu_home.xml.
<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> <item android:id="@+id/action_notifications" android:icon="@drawable/ic_menu_notifications" android:title="Notifications" app:showAsAction="always" /> </menu>
- Create a new drawable xml file in drawable directory and name it as ic_menu_notifications.xml.
- Copy paste the following in ic_menu_notifications.xml.
File: ic_menu_notifications.xml:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/ic_notification" android:drawable="@drawable/bell" android:gravity="center" /> <!-- set a place holder Drawable so android:drawable isn't null --> <item android:id="@+id/ic_badge" android:drawable="@drawable/bell" /> </layer-list>
- Now its time to code. Create a new java class and name it as BadgeDrawable.
- Copy paste the following code in BadgeDrawable.java.
import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.Typeface; import android.graphics.drawable.Drawable; public class BadgeDrawable extends Drawable { private float mTextSize; private Paint mBadgePaint; private Paint mTextPaint; private Rect mTxtRect = new Rect(); private String mCount = ""; private boolean mWillDraw = false; public BadgeDrawable(Context context) { mTextSize = context.getResources().getDimension(R.dimen.badge_text_size); mBadgePaint = new Paint(); mBadgePaint.setColor(Color.RED); mBadgePaint.setAntiAlias(true); mBadgePaint.setStyle(Paint.Style.FILL); mTextPaint = new Paint(); mTextPaint.setColor(Color.WHITE); mTextPaint.setTypeface(Typeface.DEFAULT_BOLD); mTextPaint.setTextSize(mTextSize); mTextPaint.setAntiAlias(true); mTextPaint.setTextAlign(Paint.Align.CENTER); } @Override public void draw(Canvas canvas) { if (!mWillDraw) { return; } Rect bounds = getBounds(); float width = bounds.right - bounds.left; float height = bounds.bottom - bounds.top; // Position the badge in the top-right quadrant of the icon. float radius = ((Math.min(width, height) / 2) - 1) / 2; float centerX = width - radius - 1; float centerY = radius + 1; // Draw badge circle. canvas.drawCircle(centerX, centerY, radius, mBadgePaint); // Draw badge count text inside the circle. mTextPaint.getTextBounds(mCount, 0, mCount.length(), mTxtRect); float textHeight = mTxtRect.bottom - mTxtRect.top; float textY = centerY + (textHeight / 2f); canvas.drawText(mCount, centerX, textY, mTextPaint); } /* Sets the count (i.e notifications) to display. */ public void setCount(int count) { mCount = Integer.toString(count); // Only draw a badge if there are notifications. mWillDraw = count > 0; invalidateSelf(); } @Override public void setAlpha(int alpha) { // do nothing } @Override public void setColorFilter(ColorFilter cf) { // do nothing } @Override public int getOpacity() { return PixelFormat.UNKNOWN; } }
- Create a new java class and name it as Utils.
- Copy paste the following code in Utils.java.
File: Utils.java:
import android.content.Context; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; public class Utils { public static void setBadgeCount(Context context, LayerDrawable icon, int count) { BadgeDrawable badge; // Reuse drawable if possible Drawable reuse = icon.findDrawableByLayerId(R.id.ic_badge); if (reuse != null && reuse instanceof BadgeDrawable) { badge = (BadgeDrawable) reuse; } else { badge = new BadgeDrawable(context); } badge.setCount(count); icon.mutate(); icon.setDrawableByLayerId(R.id.ic_badge, badge); } }
- Now copy paste the following code in MainActivity.java.
File: MainActivity.java:
import android.graphics.drawable.LayerDrawable; import android.os.AsyncTask; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.Menu; import android.view.MenuItem; public class MainActivity extends AppCompatActivity { private int mNotificationsCount = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new FetchCountTask().execute(); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_home, menu); // Get the notifications MenuItem and // its LayerDrawable (layer-list) MenuItem item = menu.findItem(R.id.action_notifications); LayerDrawable icon = (LayerDrawable) item.getIcon(); // Update LayerDrawable's BadgeDrawable Utils.setBadgeCount(this, icon, mNotificationsCount); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.action_notifications) { // TODO: display unread notifications. return true; } return super.onOptionsItemSelected(item); } /* Updates the count of notifications in the ActionBar. */ private void updateNotificationsBadge(int count) { mNotificationsCount = count; // force the ActionBar to relayout its MenuItems. // onCreateOptionsMenu(Menu) will be called again. invalidateOptionsMenu(); } /* Sample AsyncTask to fetch the notifications count */ class FetchCountTask extends AsyncTask<Void, Void, Integer> { @Override protected Integer doInBackground(Void... params) { // example count. This is where you'd // query your data store for the actual count. return 5; } @Override public void onPostExecute(Integer count) { updateNotificationsBadge(count); } } }
- Now run the App and enjoy the output.
Download project here
it doesnt work
ReplyDeleteit wont work becuse every website have same source code
Deletejava.lang.ClassCastException: android.graphics.drawable.BitmapDrawable cannot be cast to android.graphics.drawable.LayerDrawable............take your output
ReplyDelete