2016-05-29 73 views
0

我嘗試了所有可能的聯機方式,但是這種方法並沒有被一致地調用。 onDraw()方法有時會被調用,有時會被忽略: 請幫助我,任何幫助表示讚賞; BadgeDrawable類:(希望藉助在操作欄我的通知圖標徽章)Drawable類的OnDraw()方法沒有被調用

public class BadgeDrawable extends Drawable { 

private float mTextSize; 
private Paint mBadgePaint; 
private Paint mBadgePaint1; 
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)*/ 20; 
    mBadgePaint = new Paint(); 
    mBadgePaint.setColor(ResourceReader.getInstance(context).getColorFromResource(R.color.colorPrimary)); 
    mBadgePaint.setAntiAlias(true); 
    mBadgePaint.setStyle(Paint.Style.FILL); 
    mBadgePaint1 = new Paint(); 
    mBadgePaint1.setColor(Color.parseColor("#FFFFFF"));//white 
    mBadgePaint1.setAntiAlias(true); 
    mBadgePaint1.setStyle(Paint.Style.FILL); 

    mTextPaint = new Paint(); 
    mTextPaint.setColor(Color.WHITE); 
    mTextPaint.setTypeface(Typeface.DEFAULT); 
    mTextPaint.setTextSize(mTextSize); 
    //mTextPaint.setFlags(Paint.FAKE_BOLD_TEXT_FLAG); 
    mTextPaint.setAntiAlias(true); 
    mTextPaint.setTextAlign(Paint.Align.CENTER); 
    this.setCallback(callback); 
} 

@Override 
public void draw(Canvas canvas) { 

    Log.d("dj", "onDraw BadgeDrawable"); 
    if (!mWillDraw) { 
     return; 
    } 

    Rect bounds = getBounds(); 
    float width = bounds.right - bounds.left; 
    float height = bounds.bottom - bounds.top; 
    float radius = ((Math.max(width, height)/2))/2; 
    float centerX = (width - radius - 1) +10; 
    float centerY = radius -5; 
    if(mCount.length() <= 2){ 
     // Draw badge circle. 
     /*canvas.drawCircle(centerX, centerY, radius+9, mBadgePaint1); 
     canvas.drawCircle(centerX, centerY, radius+7, mBadgePaint);*/ 

     canvas.drawCircle(centerX, centerY, radius+9, mBadgePaint1); 
     canvas.drawCircle(centerX, centerY, radius+7, mBadgePaint); 
    } 
    else{ 
     /*canvas.drawCircle(centerX, centerY, radius+10, mBadgePaint1); 
     canvas.drawCircle(centerX, centerY, radius+8, mBadgePaint);*/ 

     canvas.drawCircle(centerX, centerY, radius+10, mBadgePaint1); 
     canvas.drawCircle(centerX, centerY, radius+8, 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); 
    /*if(mCount.length() > 2) 
    canvas.drawText("99+", centerX, textY, mTextPaint); 
    else*/ 
    canvas.drawText(mCount, centerX, textY, mTextPaint); 
} 

/* 
Sets the count (i.e notifications) to display. 
    */ 
public void setCount(String count) { 
    Log.d(Constants.TAG, "setCount count val- BadgeDrawable: "+count); 
    mCount = count; 
    // Only draw a badge if there are notifications. 
    mWillDraw = !count.equalsIgnoreCase("0"); 
    invalidateSelf(); 
} 


private Drawable.Callback callback = new Callback() { 
    @Override 
    public void invalidateDrawable(Drawable who) { 
     Log.d(Constants.TAG, "invalidateDrawable - BadgeDrawable: "); 
    } 

    @Override 
    public void scheduleDrawable(Drawable who, Runnable what, long when) { 

    } 

    @Override 
    public void unscheduleDrawable(Drawable who, Runnable what) { 

    } 
}; 

@Override 
public void setAlpha(int alpha) { 
    // do nothing 
} 

@Override 
public void setColorFilter(ColorFilter cf) { 
    // do nothing 
} 

@Override 
public int getOpacity() { 
    return PixelFormat.UNKNOWN; 
} 

}

所以,當我從服務器獲取的未讀的通知計數我這樣設置:

public static void setBadgeCount(Context context, LayerDrawable icon, String count) { 

    BadgeDrawable badge; // Reuse drawable if possible 
    Drawable reuse = icon.findDrawableByLayerId(R.id.ic_badge); //getting the layer 2 
    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); 
} 
+0

嘗試設置drawable的邊界,這是否解決了這個問題? –

+0

@Gil Moshayof我在上面,謝謝;順便說一句,我應該這樣做的構造? – DJphy

+0

這取決於 - 大部分時間你不知道你的drawable的邊界是什麼,直到度量發生,你只需要確保邊界被設置,因爲如果邊界的寬度或高度爲0,繪製方法不會被調用。 –

回答

0

確保drawable的邊界產生大於0的寬度和高度。當drawable的邊界寬度或高度爲0時,將不會調用draw方法。

您可以通過在繪圖本身上調用setBounds()來設置繪圖的邊界。

編輯

另一種獲得可拉伸重繪本身是使用層次的機制。這對繪製動畫有好處,但可以不管。

可以通過調用觸發繪製的刷新:

setLevel(getLevel() + 1) 

此外,如果你希望你的繪製重繪在一個水平變化,你需要重寫以下方法並返回true:

@Override 
protected boolean onLevelChange(int level) { 
    return true; 
} 

也許你甚至可以考慮使用級別而不是「count」變量,因爲如果級別沒有改變,重繪將不會被觸發。

希望這會有所幫助。

+0

即使如果我明確地設置邊界(調用setBounds())在構造函數中,它仍然沒有調用onDraw();在調用invalidate之前,我檢查了它顯示值的界限,但仍然沒有調用onDraw();再次可疑:) – DJphy

+0

避免在drawable上調用invalidateSelf()。相反,在保存drawable的視圖上調用postInvalidate。 –

+0

我沒有任何意見(我只處理drawables);我只是從menuitem中檢索一個圖標,例如:Drawable drw = menuItem.getIcon();我操縱這個圖標。我不能把這個可繪製的視爲一種觀點; – DJphy