答案 0 :(得分:7)
这应该是实现这个目标的方法
<强> BadgeDrawable.java 强>
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;
}
}
/res/drawable/ic_menu_notifications.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/ic_notification"
android:drawable="@drawable/ic_action_email"
android:gravity="center" />
<!-- set a place holder Drawable so android:drawable isn't null -->
<item
android:id="@+id/ic_badge"
android:drawable="@drawable/ic_action_email" />
</layer-list>
<强> /res/menu/menu_home.xml 强>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/action_notifications"
android:title="Notifications"
android:icon="@drawable/ic_menu_notifications"
android:showAsAction="always"/>
</menu>
现在位于 HomeActivity.java
public class HomeActivity extends Activity {
private int mNotificationsCount = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
// Run a task to fetch the notifications count
new FetchCountTask().execute();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.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);
}
}
}
实用工具类 Utils.java
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);
}
}
答案 1 :(得分:1)
你必须为它创建一个自定义drawable(我让你找到如何以你想要的方式创建一个)。让我们称之为myDrawable
。然后在菜单xml文件中引用它:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/myMenuId"
android:icon="@drawable/myDrawable"
android:showAsAction="always" />
</menu>
答案 2 :(得分:1)