1 /** 2 * 3 */ 4 package com.android.settings.applications; 5 6 import android.content.Context; 7 import android.graphics.Canvas; 8 import android.graphics.LinearGradient; 9 import android.graphics.Paint; 10 import android.graphics.Path; 11 import android.graphics.Rect; 12 import android.graphics.Shader; 13 import android.util.AttributeSet; 14 import android.util.DisplayMetrics; 15 import android.widget.LinearLayout; 16 17 public class LinearColorBar extends LinearLayout { 18 static final int LEFT_COLOR = 0xff0099cc; 19 static final int MIDDLE_COLOR = 0xff0099cc; 20 static final int RIGHT_COLOR = 0xff888888; 21 22 private float mRedRatio; 23 private float mYellowRatio; 24 private float mGreenRatio; 25 26 private boolean mShowingGreen; 27 28 final Rect mRect = new Rect(); 29 final Paint mPaint = new Paint(); 30 31 int mLastInterestingLeft, mLastInterestingRight; 32 int mLineWidth; 33 34 final Path mColorPath = new Path(); 35 final Path mEdgePath = new Path(); 36 final Paint mColorGradientPaint = new Paint(); 37 final Paint mEdgeGradientPaint = new Paint(); 38 39 public LinearColorBar(Context context, AttributeSet attrs) { 40 super(context, attrs); 41 setWillNotDraw(false); 42 mPaint.setStyle(Paint.Style.FILL); 43 mColorGradientPaint.setStyle(Paint.Style.FILL); 44 mColorGradientPaint.setAntiAlias(true); 45 mEdgeGradientPaint.setStyle(Paint.Style.STROKE); 46 mLineWidth = getResources().getDisplayMetrics().densityDpi >= DisplayMetrics.DENSITY_HIGH 47 ? 2 : 1; 48 mEdgeGradientPaint.setStrokeWidth(mLineWidth); 49 mEdgeGradientPaint.setAntiAlias(true); 50 51 } 52 53 public void setRatios(float red, float yellow, float green) { 54 mRedRatio = red; 55 mYellowRatio = yellow; 56 mGreenRatio = green; 57 invalidate(); 58 } 59 60 public void setShowingGreen(boolean showingGreen) { 61 if (mShowingGreen != showingGreen) { 62 mShowingGreen = showingGreen; 63 updateIndicator(); 64 invalidate(); 65 } 66 } 67 68 private void updateIndicator() { 69 int off = getPaddingTop() - getPaddingBottom(); 70 if (off < 0) off = 0; 71 mRect.top = off; 72 mRect.bottom = getHeight(); 73 if (mShowingGreen) { 74 mColorGradientPaint.setShader(new LinearGradient( 75 0, 0, 0, off-2, RIGHT_COLOR&0xffffff, RIGHT_COLOR, Shader.TileMode.CLAMP)); 76 } else { 77 mColorGradientPaint.setShader(new LinearGradient( 78 0, 0, 0, off-2, MIDDLE_COLOR&0xffffff, MIDDLE_COLOR, Shader.TileMode.CLAMP)); 79 } 80 mEdgeGradientPaint.setShader(new LinearGradient( 81 0, 0, 0, off/2, 0x00a0a0a0, 0xffa0a0a0, Shader.TileMode.CLAMP)); 82 } 83 84 @Override 85 protected void onSizeChanged(int w, int h, int oldw, int oldh) { 86 super.onSizeChanged(w, h, oldw, oldh); 87 updateIndicator(); 88 } 89 90 @Override 91 protected void onDraw(Canvas canvas) { 92 super.onDraw(canvas); 93 94 int width = getWidth(); 95 96 int left = 0; 97 98 int right = left + (int)(width*mRedRatio); 99 int right2 = right + (int)(width*mYellowRatio); 100 int right3 = right2 + (int)(width*mGreenRatio); 101 102 int indicatorLeft, indicatorRight; 103 if (mShowingGreen) { 104 indicatorLeft = right2; 105 indicatorRight = right3; 106 } else { 107 indicatorLeft = right; 108 indicatorRight = right2; 109 } 110 111 if (mLastInterestingLeft != indicatorLeft || mLastInterestingRight != indicatorRight) { 112 mColorPath.reset(); 113 mEdgePath.reset(); 114 if (indicatorLeft < indicatorRight) { 115 final int midTopY = mRect.top; 116 final int midBottomY = 0; 117 final int xoff = 2; 118 mColorPath.moveTo(indicatorLeft, mRect.top); 119 mColorPath.cubicTo(indicatorLeft, midBottomY, 120 -xoff, midTopY, 121 -xoff, 0); 122 mColorPath.lineTo(width+xoff-1, 0); 123 mColorPath.cubicTo(width+xoff-1, midTopY, 124 indicatorRight, midBottomY, 125 indicatorRight, mRect.top); 126 mColorPath.close(); 127 final float lineOffset = mLineWidth+.5f; 128 mEdgePath.moveTo(-xoff+lineOffset, 0); 129 mEdgePath.cubicTo(-xoff+lineOffset, midTopY, 130 indicatorLeft+lineOffset, midBottomY, 131 indicatorLeft+lineOffset, mRect.top); 132 mEdgePath.moveTo(width+xoff-1-lineOffset, 0); 133 mEdgePath.cubicTo(width+xoff-1-lineOffset, midTopY, 134 indicatorRight-lineOffset, midBottomY, 135 indicatorRight-lineOffset, mRect.top); 136 } 137 mLastInterestingLeft = indicatorLeft; 138 mLastInterestingRight = indicatorRight; 139 } 140 141 if (!mEdgePath.isEmpty()) { 142 canvas.drawPath(mEdgePath, mEdgeGradientPaint); 143 canvas.drawPath(mColorPath, mColorGradientPaint); 144 } 145 146 if (left < right) { 147 mRect.left = left; 148 mRect.right = right; 149 mPaint.setColor(LEFT_COLOR); 150 canvas.drawRect(mRect, mPaint); 151 width -= (right-left); 152 left = right; 153 } 154 155 right = right2; 156 157 if (left < right) { 158 mRect.left = left; 159 mRect.right = right; 160 mPaint.setColor(MIDDLE_COLOR); 161 canvas.drawRect(mRect, mPaint); 162 width -= (right-left); 163 left = right; 164 } 165 166 167 right = left + width; 168 if (left < right) { 169 mRect.left = left; 170 mRect.right = right; 171 mPaint.setColor(RIGHT_COLOR); 172 canvas.drawRect(mRect, mPaint); 173 } 174 } 175 }