2016-05-29 70 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