2013-08-09 7 views
24

Chciałbym, aby ikona powiadomienia na pasku akcji mieściła się wewnątrz liczby powiadomień.Jak zrobić ikonę na pasku akcji z numerem powiadomienia?

Na przykład (Google Adsence):

Action Bar Google Adsence

Znalazłem odpowiedź na StackOverflow, ale nie w pełni odpowiedzieć na moje pytanie, ponieważ w tym przypadku jest to tylko liczba, a nie ikona z numerem : Actionbar notification icon with count

+1

Podejście będzie dokładnie takie samo, jak w przypadku innej odpowiedzi. Trzeba tylko stworzyć inny obraz dla tła. Korzystanie z dziewięciu łatek pozwala łatwo zrównoważyć liczbę, jak na zdjęciu. – Grimmace

+1

@Grimmace ma rację. Myślę, że szukasz tych pytań: http://stackoverflow.com/questions/6011786/add-new-item-count-to-icon-on-button-android http://stackoverflow.com/questions/13288989/ how-to-get-text-on-a-actionbar-icon Mam nadzieję, że rozwiąże twój problem. –

Odpowiedz

29

Po wielu próbach prawie wszystkich zasobów na SO zwróciłem się do blogów; z powodzeniem. Chcę podzielić się tym, co dla mnie zadziałało (Api> = 13).

Zacznijmy sposób jest on wykorzystywany w kodzie:

public boolean onCreateOptionsMenu(Menu menu) { 
    //inflate menu 
    getMenuInflater().inflate(R.menu.menu_my, menu); 

    // Get the notifications MenuItem and LayerDrawable (layer-list) 
    MenuItem item = menu.findItem(R.id.action_notifications); 
    LayerDrawable icon = (LayerDrawable) item.getIcon(); 

    // Update LayerDrawable's BadgeDrawable 
    Utils2.setBadgeCount(this, icon, 2); 

    return true; 
} 

menu_my.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_notifications" 
     android:icon="@drawable/ic_menu_notifications" 
     android:title="Notifications" 
     app:showAsAction="always" /> 
</menu> 

Ta klasa, która wygodnie robi BadgeDrawable:

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); 
     mTextSize = 12F; 

     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; 
    } 
} 

tej klasie to pomaga ustawić numer.

public class Utils2 { 
    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); 
    } 


} 

I mui Ważne rozciągliwej (jak układ) w res/drawable:

<?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/ice_skate" 
     android:gravity="center" /> 

    <!-- set a place holder Drawable so android:drawable isn't null --> 
    <item 
     android:id="@+id/ic_badge" 
     android:drawable="@drawable/ice_skate" /> 
</layer-list> 

Powodzenia!

+0

Może być lepszy sposób na zrobienie tego. http://stackoverflow.com/questions/17696486/actionbar-notification-count-badge-like-google-has – Bikash

+0

Nie sprawdzałem kodu. Myślę, że to pomogłoby powiedzieć, dlaczego byłoby lepiej. Dzięki. – msysmilu

+0

Link _Source_ jest martwy lub taki link się nie kończy, Kindly update @msysmilu –