private void drawCircle(Canvas canvas, BatteryTracker tracker, float textX, RectF drawRect) { boolean unknownStatus = tracker.status == BatteryManager.BATTERY_STATUS_UNKNOWN; int animOffset = tracker.shouldIndicateCharging() ? mAnimOffset : 0; int level = tracker.level; Paint paint; if (unknownStatus) { paint = mBackPaint; level = 100; // Draw all the circle; } else { paint = mFrontPaint; paint.setColor(getColorForLevel(level)); if (tracker.status == BatteryManager.BATTERY_STATUS_FULL) { level = 100; } } // draw thin gray ring first canvas.drawArc(drawRect, 270, 360, false, mBackPaint); // draw colored arc representing charge level canvas.drawArc(drawRect, 270 + animOffset, 3.6f * level, false, paint); // if chosen by options, draw percentage text in the middle // always skip percentage when 100, so layout doesnt break if (unknownStatus) { mTextPaint.setColor(paint.getColor()); canvas.drawText("?", textX, mTextY, mTextPaint); } else if (tracker.shouldIndicateCharging() && (!mShowPercent || level == 100)) { // draw the bolt final float bl = (int) (drawRect.left + drawRect.width() / 3.2f); final float bt = (int) (drawRect.top + drawRect.height() / 4f); final float br = (int) (drawRect.right - drawRect.width() / 5.2f); final float bb = (int) (drawRect.bottom - drawRect.height() / 8f); if (mBoltFrame.left != bl || mBoltFrame.top != bt || mBoltFrame.right != br || mBoltFrame.bottom != bb) { mBoltFrame.set(bl, bt, br, bb); mBoltPath.reset(); mBoltPath.moveTo( mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(), mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height()); for (int i = 2; i < mBoltPoints.length; i += 2) { mBoltPath.lineTo( mBoltFrame.left + mBoltPoints[i] * mBoltFrame.width(), mBoltFrame.top + mBoltPoints[i + 1] * mBoltFrame.height()); } mBoltPath.lineTo( mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(), mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height()); } canvas.drawPath(mBoltPath, mBoltPaint); } else if (level < 100 && mShowPercent) { mTextPaint.setColor(paint.getColor()); canvas.drawText(Integer.toString(level), textX, mTextY, mTextPaint); } }
@Override public void dispatchDemoCommand(String command, Bundle args) { if (getVisibility() == View.VISIBLE) { if (!mDemoMode && command.equals(COMMAND_ENTER)) { mDemoMode = true; mDemoTracker.level = mTracker.level; mDemoTracker.plugged = mTracker.plugged; } else if (mDemoMode && command.equals(COMMAND_EXIT)) { mDemoMode = false; postInvalidate(); } else if (mDemoMode && command.equals(COMMAND_BATTERY)) { String level = args.getString("level"); String plugged = args.getString("plugged"); if (level != null) { mDemoTracker.level = Math.min(Math.max(Integer.parseInt(level), 0), 100); } if (plugged != null) { mDemoTracker.plugged = Boolean.parseBoolean(plugged); } postInvalidate(); } } }
@Override public void onAttachedToWindow() { super.onAttachedToWindow(); IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_BATTERY_CHANGED); filter.addAction(ACTION_LEVEL_TEST); final Intent sticky = getContext().registerReceiver(mTracker, filter); if (sticky != null) { // preload the battery level mTracker.onReceive(getContext(), sticky); } mAttached = true; }
private void updateChargeAnimation(BatteryTracker tracker) { if (!tracker.shouldIndicateCharging()) { resetChargeAnimation(); return; } mIsAnimating = true; if (mAnimOffset > 100) { mAnimOffset = 0; } else { mAnimOffset += 5; } mHandler.removeCallbacks(mInvalidate); mHandler.postDelayed(mInvalidate, 100); }
@Override public void onDraw(Canvas c, BatteryTracker tracker) { if (mDisposed) return; int level = tracker.level; boolean plugged = tracker.plugged; boolean unknownStatus = tracker.status == BatteryManager.BATTERY_STATUS_UNKNOWN; if (mOldLevel != level || mOldPlugged != plugged) { mOldLevel = level; mOldPlugged = plugged; postInvalidate(); requestLayout(); return; } if (unknownStatus) { c.drawText("?", mTextX, mTextY, mBackPaint); Resources res = mContext.getResources(); mFrontPaint.setColor(res.getColor(R.color.batterymeter_frame_color)); drawWithoutLevel(c, "?"); return; } mFrontPaint.setColor(getColorForLevel(level)); // Is plugged? Then use the animation status if (tracker.shouldIndicateCharging() && level != 100) { updateChargeAnimation(tracker); drawWithLevel(c, tracker, mAnimOffset, getLevel(level)); } else { resetChargeAnimation(); if (DRAW_LEVEL) { drawWithLevel(c, tracker, level, getLevel(level)); } else { drawWithoutLevel(c, getLevel(level)); } } }
/** * updates the animation counter cares for timed callbacks to continue animation cycles uses * mInvalidate for delayed invalidate() callbacks */ private void updateChargeAnim(BatteryTracker tracker) { if (!tracker.shouldIndicateCharging() || tracker.status == BatteryManager.BATTERY_STATUS_FULL) { if (mIsAnimating) { mIsAnimating = false; mAnimOffset = 0; mHandler.removeCallbacks(mInvalidate); } return; } mIsAnimating = true; if (mAnimOffset > 360) { mAnimOffset = 0; } else { mAnimOffset += 3; } mHandler.removeCallbacks(mInvalidate); mHandler.postDelayed(mInvalidate, 50); }
@Override public void onDraw(Canvas c, BatteryTracker tracker) { if (mDisposed) return; final int level = tracker.level; if (level == BatteryTracker.UNKNOWN_LEVEL) return; float drawFrac = (float) level / 100f; final int pt = getPaddingTop() + (mHorizontal ? (int) (mHeight * 0.20f) : 0); final int pl = getPaddingLeft(); final int pr = getPaddingRight(); final int pb = getPaddingBottom(); int height = mHeight - pt - pb; int width = mWidth - pl - pr; mButtonHeight = (int) ((mHorizontal ? width : height) * 0.12f); mFrame.set(0, 0, width, height); mFrame.offset(pl, pt); if (mHorizontal) { mButtonFrame.set( /*cover frame border of intersecting area*/ width - (mButtonHeight + 5) - mFrame.left, mFrame.top + height * 0.25f, mFrame.right, mFrame.bottom - height * 0.25f); mButtonFrame.top += SUBPIXEL; mButtonFrame.bottom -= SUBPIXEL; mButtonFrame.right -= SUBPIXEL; } else { mButtonFrame.set( mFrame.left + width * 0.25f, mFrame.top, mFrame.right - width * 0.25f, mFrame.top + mButtonHeight + 5 /*cover frame border of intersecting area*/); mButtonFrame.top += SUBPIXEL; mButtonFrame.left += SUBPIXEL; mButtonFrame.right -= SUBPIXEL; } if (mHorizontal) { mFrame.right -= mButtonHeight; } else { mFrame.top += mButtonHeight; } mFrame.left += SUBPIXEL; mFrame.top += SUBPIXEL; mFrame.right -= SUBPIXEL; mFrame.bottom -= SUBPIXEL; // first, draw the battery shape c.drawRect(mFrame, mFramePaint); // fill 'er up final int color = tracker.plugged ? mChargeColor : getColorForLevel(level); mBatteryPaint.setColor(color); if (level >= FULL) { drawFrac = 1f; } else if (level <= EMPTY) { drawFrac = 0f; } c.drawRect(mButtonFrame, drawFrac == 1f ? mBatteryPaint : mFramePaint); mClipFrame.set(mFrame); if (mHorizontal) { mClipFrame.right -= (mFrame.width() * (1f - drawFrac)); } else { mClipFrame.top += (mFrame.height() * (1f - drawFrac)); } c.save(Canvas.CLIP_SAVE_FLAG); c.clipRect(mClipFrame); c.drawRect(mFrame, mBatteryPaint); c.restore(); if (tracker.shouldIndicateCharging()) { // draw the bolt final float bl = (int) (mFrame.left + mFrame.width() / (mHorizontal ? 9f : 4.5f)); final float bt = (int) (mFrame.top + mFrame.height() / (mHorizontal ? 4.5f : 6f)); final float br = (int) (mFrame.right - mFrame.width() / (mHorizontal ? 6f : 7f)); final float bb = (int) (mFrame.bottom - mFrame.height() / (mHorizontal ? 7f : 10f)); if (mBoltFrame.left != bl || mBoltFrame.top != bt || mBoltFrame.right != br || mBoltFrame.bottom != bb) { mBoltFrame.set(bl, bt, br, bb); mBoltPath.reset(); mBoltPath.moveTo( mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(), mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height()); for (int i = 2; i < mBoltPoints.length; i += 2) { mBoltPath.lineTo( mBoltFrame.left + mBoltPoints[i] * mBoltFrame.width(), mBoltFrame.top + mBoltPoints[i + 1] * mBoltFrame.height()); } mBoltPath.lineTo( mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(), mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height()); } c.drawPath(mBoltPath, mBoltPaint); } else if (level <= EMPTY) { final float x = mHorizontal ? pt + (height * 0.5f) : mWidth * 0.5f; final float y = mHorizontal ? (mWidth - mWarningTextHeight) * -0.48f : (mHeight + mWarningTextHeight) * 0.48f; if (mHorizontal) { c.save(); c.rotate(90); } c.drawText(mWarningString, x, y, mWarningTextPaint); if (mHorizontal) { c.restore(); } } else if (mShowPercent && !(tracker.level == 100 && !SHOW_100_PERCENT)) { final float full = mHorizontal ? 0.60f : 0.45f; final float nofull = mHorizontal ? 0.75f : 0.6f; final float single = mHorizontal ? 0.86f : 0.75f; mTextPaint.setTextSize( height * (SINGLE_DIGIT_PERCENT ? single : (tracker.level == 100 ? full : nofull))); mTextHeight = -mTextPaint.getFontMetrics().ascent; final String str = String.valueOf(SINGLE_DIGIT_PERCENT ? (level / 10) : level); final float x = mWidth * 0.5f; final float y = pt + (height + mTextHeight) * 0.47f; c.drawText(str, x, y, mTextPaint); } }