Draw percentage information into BatteryChartView manually

screen: https://screenshot.googleplex.com/Bw4Whpzff5pCT5J

Bug: 183921876
Test: make SettingsRoboTests
Test: make SettingsGoogleRoboTests
Change-Id: I61c0f73e27dc2980d0812e00c2fdfda9a628b696
This commit is contained in:
ykhung
2021-04-26 11:53:38 +08:00
committed by YUKAI HUNG
parent 5f876de174
commit 1001614b14
4 changed files with 95 additions and 19 deletions

View File

@@ -26,7 +26,7 @@
android:id="@+id/chart_summary" android:id="@+id/chart_summary"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="45dp" android:layout_marginBottom="30dp"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
settings:textColor="?android:attr/textColorSecondary" settings:textColor="?android:attr/textColorSecondary"
android:text="@string/battery_usage_chart_graph_hint" /> android:text="@string/battery_usage_chart_graph_hint" />
@@ -34,9 +34,16 @@
<com.android.settings.fuelgauge.BatteryChartView <com.android.settings.fuelgauge.BatteryChartView
android:id="@+id/battery_chart" android:id="@+id/battery_chart"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="141dp" android:layout_height="150dp"
android:layout_marginBottom="16dp" android:layout_marginBottom="16dp"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
settings:textColor="?android:attr/textColorSecondary" /> settings:textColor="?android:attr/textColorSecondary" />
<TextView
android:id="@+id/companion_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"/>
</LinearLayout> </LinearLayout>

View File

@@ -441,6 +441,7 @@
<dimen name="subtitle_bottom_padding">24dp</dimen> <dimen name="subtitle_bottom_padding">24dp</dimen>
<!-- Battery usage chart view component --> <!-- Battery usage chart view component -->
<dimen name="chartview_text_padding">3dp</dimen>
<dimen name="chartview_divider_width">1dp</dimen> <dimen name="chartview_divider_width">1dp</dimen>
<dimen name="chartview_divider_height">4dp</dimen> <dimen name="chartview_divider_height">4dp</dimen>
<dimen name="chartview_trapezoid_radius">3dp</dimen> <dimen name="chartview_trapezoid_radius">3dp</dimen>

View File

@@ -22,11 +22,13 @@ import android.graphics.Color;
import android.graphics.CornerPathEffect; import android.graphics.CornerPathEffect;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.Rect;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
import android.view.HapticFeedbackConstants; import android.view.HapticFeedbackConstants;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.widget.TextView;
import androidx.appcompat.widget.AppCompatImageView; import androidx.appcompat.widget.AppCompatImageView;
@@ -38,6 +40,8 @@ import java.util.Locale;
/** A widget component to draw chart graph. */ /** A widget component to draw chart graph. */
public class BatteryChartView extends AppCompatImageView implements View.OnClickListener { public class BatteryChartView extends AppCompatImageView implements View.OnClickListener {
private static final String TAG = "BatteryChartView"; private static final String TAG = "BatteryChartView";
// For drawing the percentage information.
private static final String[] PERCENTAGES = new String[] {"100%", "50%", "0%"};
private static final int DEFAULT_TRAPEZOID_COUNT = 12; private static final int DEFAULT_TRAPEZOID_COUNT = 12;
/** Selects all trapezoid shapes. */ /** Selects all trapezoid shapes. */
public static final int SELECTED_INDEX_ALL = -1; public static final int SELECTED_INDEX_ALL = -1;
@@ -58,8 +62,14 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
private int mTrapezoidColor; private int mTrapezoidColor;
private int mTrapezoidSolidColor; private int mTrapezoidSolidColor;
private final int mDividerColor = Color.parseColor("#CDCCC5"); private final int mDividerColor = Color.parseColor("#CDCCC5");
// For drawing the percentage information.
private int mTextPadding;
private final Rect mIndent = new Rect();
private final Rect[] mPercentageBound =
new Rect[] {new Rect(), new Rect(), new Rect()};
private int[] mLevels; private int[] mLevels;
private Paint mTextPaint;
private Paint mDividerPaint; private Paint mDividerPaint;
private Paint mTrapezoidPaint; private Paint mTrapezoidPaint;
private TrapezoidSlot[] mTrapezoidSlot; private TrapezoidSlot[] mTrapezoidSlot;
@@ -128,6 +138,37 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
mOnSelectListener = listener; mOnSelectListener = listener;
} }
/** Sets the companion {@link TextView} for percentage information. */
public void setCompanionTextView(TextView textView) {
requestLayout();
if (textView != null) {
// Pre-draws the view first to load style atttributions into paint.
textView.draw(new Canvas());
mTextPaint = textView.getPaint();
} else {
mTextPaint = null;
}
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// Measures text bounds and updates indent configuration.
if (mTextPaint != null) {
for (int index = 0; index < PERCENTAGES.length; index++) {
mTextPaint.getTextBounds(
PERCENTAGES[index], 0, PERCENTAGES[index].length(),
mPercentageBound[index]);
}
// Updates the indent configurations.
mIndent.top = mPercentageBound[0].height();
mIndent.right = mPercentageBound[0].width() + mTextPadding * 2;
Log.d(TAG, "setIndent:" + mPercentageBound[0]);
} else {
mIndent.set(0, 0, 0, 0);
}
}
@Override @Override
public void draw(Canvas canvas) { public void draw(Canvas canvas) {
super.draw(canvas); super.draw(canvas);
@@ -194,32 +235,56 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
mTrapezoidPaint.setPathEffect( mTrapezoidPaint.setPathEffect(
new CornerPathEffect( new CornerPathEffect(
resources.getDimensionPixelSize(R.dimen.chartview_trapezoid_radius))); resources.getDimensionPixelSize(R.dimen.chartview_trapezoid_radius)));
// Initializes for drawing text information.
mTextPadding = resources.getDimensionPixelSize(R.dimen.chartview_text_padding);
} }
private void drawHorizontalDividers(Canvas canvas) { private void drawHorizontalDividers(Canvas canvas) {
final int width = getWidth() - mIndent.right;
final int height = getHeight() - mIndent.top - mIndent.bottom;
// Draws the top divider line for 100% curve. // Draws the top divider line for 100% curve.
float offsetY = mDividerWidth * 0.5f; float offsetY = mIndent.top + mDividerWidth * .5f;
canvas.drawLine(0, offsetY, getWidth(), offsetY, mDividerPaint); canvas.drawLine(0, offsetY, width, offsetY, mDividerPaint);
if (mTextPaint != null) {
canvas.drawText(
PERCENTAGES[0],
getWidth() - mPercentageBound[0].width(),
offsetY + mPercentageBound[0].height() *.5f , mTextPaint);
}
// Draws the center divider line for 50% curve. // Draws the center divider line for 50% curve.
final float availableSpace = final float availableSpace =
getHeight() - mDividerWidth * 2 - mTrapezoidVOffset - mDividerHeight; height - mDividerWidth * 2 - mTrapezoidVOffset - mDividerHeight;
offsetY = mDividerWidth + availableSpace * 0.5f; offsetY = mIndent.top + mDividerWidth + availableSpace * .5f;
canvas.drawLine(0, offsetY, getWidth(), offsetY, mDividerPaint); canvas.drawLine(0, offsetY, width, offsetY, mDividerPaint);
// Draws the center divider line for 0% curve. if (mTextPaint != null) {
offsetY = getHeight() - mDividerHeight - mDividerWidth * 0.5f; canvas.drawText(
canvas.drawLine(0, offsetY, getWidth(), offsetY, mDividerPaint); PERCENTAGES[1],
getWidth() - mPercentageBound[1].width(),
offsetY + mPercentageBound[1].height() *.5f , mTextPaint);
}
// Draws the bottom divider line for 0% curve.
offsetY = mIndent.top + (height - mDividerHeight - mDividerWidth * .5f);
canvas.drawLine(0, offsetY, width, offsetY, mDividerPaint);
if (mTextPaint != null) {
canvas.drawText(
PERCENTAGES[2],
getWidth() - mPercentageBound[2].width(),
offsetY + mPercentageBound[2].height() *.5f , mTextPaint);
}
} }
private void drawVerticalDividers(Canvas canvas) { private void drawVerticalDividers(Canvas canvas) {
final int width = getWidth() - mIndent.right;
final int dividerCount = mTrapezoidCount + 1; final int dividerCount = mTrapezoidCount + 1;
final float dividerSpace = dividerCount * mDividerWidth; final float dividerSpace = dividerCount * mDividerWidth;
final float unitWidth = (getWidth() - dividerSpace) / (float) mTrapezoidCount; final float unitWidth = (width - dividerSpace) / (float) mTrapezoidCount;
final float startY = getHeight() - mDividerHeight; final float bottomY = getHeight() - mIndent.bottom;
final float trapezoidSlotOffset = mTrapezoidHOffset + mDividerWidth * 0.5f; final float startY = bottomY - mDividerHeight;
final float trapezoidSlotOffset = mTrapezoidHOffset + mDividerWidth * .5f;
// Draws each vertical dividers. // Draws each vertical dividers.
float startX = mDividerWidth * 0.5f; float startX = mDividerWidth * .5f;
for (int index = 0; index < dividerCount; index++) { for (int index = 0; index < dividerCount; index++) {
canvas.drawLine(startX, startY, startX, getHeight(), mDividerPaint); canvas.drawLine(startX, startY, startX, bottomY, mDividerPaint);
final float nextX = startX + mDividerWidth + unitWidth; final float nextX = startX + mDividerWidth + unitWidth;
// Updates the trapezoid slots for drawing. // Updates the trapezoid slots for drawing.
if (index < mTrapezoidSlot.length) { if (index < mTrapezoidSlot.length) {
@@ -236,8 +301,9 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
return; return;
} }
final float trapezoidBottom = final float trapezoidBottom =
getHeight() - mDividerHeight - mDividerWidth - mTrapezoidVOffset; getHeight() - mIndent.bottom - mDividerHeight - mDividerWidth
final float availableSpace = trapezoidBottom - mDividerWidth; - mTrapezoidVOffset;
final float availableSpace = trapezoidBottom - mDividerWidth * .5f - mIndent.top;
final float unitHeight = availableSpace / 100f; final float unitHeight = availableSpace / 100f;
// Draws all trapezoid shapes into the canvas. // Draws all trapezoid shapes into the canvas.
final Path trapezoidPath = new Path(); final Path trapezoidPath = new Path();

View File

@@ -100,6 +100,8 @@ public class BatteryHistoryPreference extends Preference {
} }
if (mIsChartGraphEnabled) { if (mIsChartGraphEnabled) {
mBatteryChartView = (BatteryChartView) view.findViewById(R.id.battery_chart); mBatteryChartView = (BatteryChartView) view.findViewById(R.id.battery_chart);
mBatteryChartView.setCompanionTextView(
(TextView) view.findViewById(R.id.companion_text));
if (mChartPreferenceController != null) { if (mChartPreferenceController != null) {
mChartPreferenceController.setBatteryChartView(mBatteryChartView); mChartPreferenceController.setBatteryChartView(mBatteryChartView);
} }