【问题标题】:OnDraw() method of Drawable class is not getting calledDrawable 类的 OnDraw() 方法没有被调用
【发布时间】:2018-04-08 03:48:33
【问题描述】:

我已经尝试了所有可能的在线可用方法,但这种方法并没有被一致地调用。 onDraw() 方法有时会被调用,有时只是被忽略: 请,请帮助我,任何帮助表示赞赏; BadgeDrawable 类:(想在操作栏中的通知图标上绘制徽章)

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

【问题讨论】:

  • 尝试设置drawable的边界,这样能解决问题吗?
  • @Gil Moshayof 我同意了,谢谢;顺便说一句,我应该在构造函数中这样做吗??
  • 这取决于 - 大多数时候你不知道你的drawable的边界是什么直到测量发生,你只需要确保设置了边界,因为如果宽度或高度bounds 为 0,draw 方法不会被调用。
  • @Gil Moshayof 我正在寻找 whr to 以及如何为可绘制对象设置边界(正确的边界方法)。我会尽快回来更新 :) 并且它有时会调用而不是其他时候调用(这很奇怪和神秘)
  • @Gil Moshayof 你的 100% 正确,如果边界为 0,它不会调用绘制;神秘地有时它是 0 有时它不是;顺便说一句,我使用的drawable wic在xml中托管了一个drawable(background@drawable/my_icon);实际上它不能为零;我在调用 invalidateSelf() 并设置一些虚拟 val 之前尝试调用 setBounds 是否足够公平,所以它调用 onDraw();请,请回复这个...非常感谢这个宝贵的信息

标签: android android-drawable ondraw


【解决方案1】:

我知道为时已晚。答案是

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);
    icon.mutate();
    icon.setDrawableByLayerId(R.id.ic_badge, badge);
}

badge.setCount(count);

}

【讨论】:

    【解决方案2】:

    确保drawable的bounds产生大于0的宽度和高度。当drawable的bounds的宽度或高度为0时,draw方法将不会被调用。

    您可以通过在可绘制对象本身上调用setBounds() 来设置可绘制对象的边界。

    编辑

    另一种让可绘制对象重绘自身的方法是使用关卡机制。这对于动画的可绘制对象很有用,但无论如何都可以使用。

    你可以通过调用来触发drawable的刷新:

    setLevel(getLevel() + 1)
    

    另外,如果你想让你的drawable在关卡改变时重绘,你需要重写下面的方法并返回true:

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

    也许您甚至可以考虑使用关卡而不是“计数”变量,因为如果关卡没有改变,则不会触发重绘。

    希望这会有所帮助。

    【讨论】:

    • 即使我在构造函数中明确设置边界(调用 setBounds()),它仍然没有调用 onDraw();在调用无效之前,我检查了它显示我设置的值但仍然没有调用 onDraw() 的边界;再次可疑:)
    • 避免在可绘制对象上调用 invalidateSelf()。相反,在包含可绘制对象的视图上调用 postInvalidate。
    • 我在这里没有任何意见(我只处理drawables);我只是从 menuitem 中检索一个图标,例如: Drawable drw = menuItem.getIcon();我操纵这个图标。我不能将此可绘制对象视为视图;
    • 再次感谢,我会检查一下
    猜你喜欢
    • 1970-01-01
    • 2011-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-31
    • 2016-10-30
    相关资源
    最近更新 更多