Here are the examples of the java api android.graphics.PathEffect taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.
67 Examples
19
Source : SunriseSunsetView.java
with Apache License 2.0
from tianma8023
with Apache License 2.0
from tianma8023
public void setTrackPathEffect(PathEffect trackPathEffect) {
mTrackPathEffect = trackPathEffect;
}
19
Source : AbstractPaintSubject.java
with Apache License 2.0
from pkware
with Apache License 2.0
from pkware
public void hasPathEffect(@Nullable PathEffect effect) {
check("getPathEffect()").that(actual.getPathEffect()).isSameInstanceAs(effect);
}
19
Source : CustomCalendar.java
with Apache License 2.0
from openXu
with Apache License 2.0
from openXu
/**
* 绘制某一行的日期
* @param canvas
* @param top 顶部坐标
* @param count 此行需要绘制的日期数量(不一定都是7天)
* @param overDay 已经绘制过的日期,从overDay+1开始绘制
* @param startIndex 此行第一个日期的星期索引
*/
private void drawDayAndPre(Canvas canvas, float top, int count, int overDay, int startIndex) {
// Log.e(TAG, "总共"+dayOfMonth+"天 有"+lineNum+"行"+ " 已经画了"+overDay+"天,下面绘制:"+count+"天");
// 背景
float topPre = top + mLineSpac + dayHeight;
bgPaint.setColor(mBgDay);
RectF rect = new RectF(0, top, getWidth(), topPre);
canvas.drawRect(rect, bgPaint);
bgPaint.setColor(mBgPre);
rect = new RectF(0, topPre, getWidth(), topPre + mTextSpac + dayHeight);
canvas.drawRect(rect, bgPaint);
mPaint.setTextSize(mTextSizeDay);
float dayTextLeading = FontUtil.getFontLeading(mPaint);
mPaint.setTextSize(mTextSizePre);
float preTextLeading = FontUtil.getFontLeading(mPaint);
// Log.v(TAG, "当前日期:"+currentDay+" 选择日期:"+selectDay+" 是否为当前月:"+isCurrentMonth);
for (int i = 0; i < count; i++) {
int left = (startIndex + i) * columnWidth;
int day = (overDay + i + 1);
mPaint.setTextSize(mTextSizeDay);
// 如果是当前月,当天日期需要做处理
if (isCurrentMonth && currentDay == day) {
mPaint.setColor(mTextColorDay);
bgPaint.setColor(mCurrentBg);
// 空心
bgPaint.setStyle(Paint.Style.STROKE);
PathEffect effect = new DashPathEffect(mCurrentBgDashPath, 1);
// 设置画笔曲线间隔
bgPaint.setPathEffect(effect);
// 画笔宽度
bgPaint.setStrokeWidth(mCurrentBgStrokeWidth);
// 绘制空心圆背景
canvas.drawCircle(left + columnWidth / 2, top + mLineSpac + dayHeight / 2, mSelectRadius - mCurrentBgStrokeWidth, bgPaint);
}
// 绘制完后将画笔还原,避免脏笔
bgPaint.setPathEffect(null);
bgPaint.setStrokeWidth(0);
bgPaint.setStyle(Paint.Style.FILL);
// 选中的日期,如果是本月,选中日期正好是当天日期,下面的背景会覆盖上面绘制的虚线背景
if (selectDay == day) {
// 选中的日期字体白色,橙色背景
mPaint.setColor(mSelectTextColor);
bgPaint.setColor(mSelectBg);
// 绘制橙色圆背景,参数一是中心点的x轴,参数二是中心点的y轴,参数三是半径,参数四是paint对象;
canvas.drawCircle(left + columnWidth / 2, top + mLineSpac + dayHeight / 2, mSelectRadius, bgPaint);
} else {
mPaint.setColor(mTextColorDay);
}
int len = (int) FontUtil.getFontlength(mPaint, day + "");
int x = left + (columnWidth - len) / 2;
canvas.drawText(day + "", x, top + mLineSpac + dayTextLeading, mPaint);
// 绘制次数
mPaint.setTextSize(mTextSizePre);
DayFinish finish = map.get(day);
String preStr = "0/0";
if (isCurrentMonth) {
if (day > currentDay) {
mPaint.setColor(mTextColorPreNull);
} else if (finish != null) {
// 区分完成未完成
if (finish.finish >= finish.all) {
mPaint.setColor(mTextColorPreFinish);
} else {
mPaint.setColor(mTextColorPreUnFinish);
}
preStr = finish.finish + "/" + finish.all;
} else {
mPaint.setColor(mTextColorPreNull);
}
} else {
if (finish != null) {
// 区分完成未完成
if (finish.finish >= finish.all) {
mPaint.setColor(mTextColorPreFinish);
} else {
mPaint.setColor(mTextColorPreUnFinish);
}
preStr = finish.finish + "/" + finish.all;
} else {
mPaint.setColor(mTextColorPreNull);
}
}
len = (int) FontUtil.getFontlength(mPaint, preStr);
x = left + (columnWidth - len) / 2;
canvas.drawText(preStr, x, topPre + mTextSpac + preTextLeading, mPaint);
}
}
19
Source : Line.java
with Apache License 2.0
from lwd1815
with Apache License 2.0
from lwd1815
/**
* Sets the path effect.
*
* @param pe
* {@link PathEffect PathEffect} for line drawing
* @return this
*/
public Line setPathEffect(PathEffect pe) {
mPaint.setPathEffect(pe);
return this;
}
19
Source : JustContext.java
with MIT License
from LiuHongtao
with MIT License
from LiuHongtao
public void setLineDash(V8Array intervals) {
float[] floatIntervals = new float[intervals.length()];
for (int i = 0; i < intervals.length(); i++) {
floatIntervals[i] = (float) ((double) intervals.getDouble(i));
}
PathEffect effects = new DashPathEffect(floatIntervals, 1);
mPaintStroke.setPathEffect(effects);
intervals.release();
}
19
Source : ChartLineView.java
with MIT License
from lihangleo2
with MIT License
from lihangleo2
private void drawLine(Canvas canvas) {
for (int i = 0; i < utilBeans.size(); i++) {
ChartUtilBean chartUtilBean = utilBeans.get(i);
// 绘制渐变阴影
if (items.get(i).isWithShadow()) {
canvas.drawPath(chartUtilBean.getmPathShadow(), chartUtilBean.getmPaintShadow());
}
// 是否带动画
if (items.get(i).isWithAnim()) {
PathMeasure measure = new PathMeasure(chartUtilBean.getmPath(), false);
float pathLength = measure.getLength();
PathEffect effect = new DashPathEffect(new float[] { pathLength, pathLength }, pathLength - pathLength * mProgress);
chartUtilBean.getmPaintLine().setPathEffect(effect);
}
canvas.drawPath(chartUtilBean.getmPath(), chartUtilBean.getmPaintLine());
}
}
19
Source : ChartHistogramView.java
with MIT License
from lihangleo2
with MIT License
from lihangleo2
private void drawLine(Canvas canvas) {
for (int i = 0; i < utilBeans.size(); i++) {
ChartUtilBean chartUtilBean = utilBeans.get(i);
// 绘制渐变阴影
canvas.drawPath(chartUtilBean.getmPathShadow(), chartUtilBean.getmPaintShadow());
// 是否带动画
if (items.get(i).isWithAnim()) {
PathMeasure measure = new PathMeasure(chartUtilBean.getmPath(), false);
float pathLength = measure.getLength();
PathEffect effect = new DashPathEffect(new float[] { pathLength, pathLength }, pathLength - pathLength * mProgress);
chartUtilBean.getmPaintLine().setPathEffect(effect);
}
canvas.drawPath(chartUtilBean.getmPath(), chartUtilBean.getmPaintLine());
}
}
19
Source : Line.java
with Apache License 2.0
from huashengzzz
with Apache License 2.0
from huashengzzz
/**
* Set path effect for this line, note: it will slow down drawing, try to not use complicated effects,
* DashPathEffect should be safe choice.
*
* @param pathEffect
*/
public void setPathEffect(PathEffect pathEffect) {
this.pathEffect = pathEffect;
}
19
Source : Shape.java
with Apache License 2.0
from florent37
with Apache License 2.0
from florent37
public Shape setPathEffect(final PathEffect pathEffect) {
paint.setPathEffect(pathEffect);
return this;
}
19
Source : LineShape.java
with Apache License 2.0
from florent37
with Apache License 2.0
from florent37
public LineShape setPathEffect(final PathEffect pathEffect) {
return (LineShape) super.setPathEffect(pathEffect);
}
19
Source : Border.java
with Apache License 2.0
from facebook
with Apache License 2.0
from facebook
/**
* Represents a collection of attributes that describe how a border should be applied to a layout
*/
public clreplaced Border implements Equivalence<Border> {
static final int EDGE_LEFT = 0;
static final int EDGE_TOP = 1;
static final int EDGE_RIGHT = 2;
static final int EDGE_BOTTOM = 3;
static final int EDGE_COUNT = 4;
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true, value = { Corner.TOP_LEFT, Corner.TOP_RIGHT, Corner.BOTTOM_RIGHT, Corner.BOTTOM_LEFT })
public @interface Corner {
int TOP_LEFT = 0;
int TOP_RIGHT = 1;
int BOTTOM_RIGHT = 2;
int BOTTOM_LEFT = 3;
}
static final int RADIUS_COUNT = 4;
final float[] mRadius = new float[RADIUS_COUNT];
final int[] mEdgeWidths = new int[EDGE_COUNT];
final int[] mEdgeColors = new int[EDGE_COUNT];
PathEffect mPathEffect;
public static Builder create(ComponentContext context) {
return new Builder(context);
}
private Border() {
}
void setEdgeWidth(YogaEdge edge, int width) {
if (width < 0) {
throw new IllegalArgumentException("Given negative border width value: " + width + " for edge " + edge.name());
}
setEdgeValue(mEdgeWidths, edge, width);
}
void setEdgeColor(YogaEdge edge, @ColorInt int color) {
setEdgeValue(mEdgeColors, edge, color);
}
static int getEdgeColor(int[] colorArray, YogaEdge edge) {
if (colorArray.length != EDGE_COUNT) {
throw new IllegalArgumentException("Given wrongly sized array");
}
return colorArray[edgeIndex(edge)];
}
static YogaEdge edgeFromIndex(int i) {
if (i < 0 || i >= EDGE_COUNT) {
throw new IllegalArgumentException("Given index out of range of acceptable edges: " + i);
}
switch(i) {
case EDGE_LEFT:
return YogaEdge.LEFT;
case EDGE_TOP:
return YogaEdge.TOP;
case EDGE_RIGHT:
return YogaEdge.RIGHT;
case EDGE_BOTTOM:
return YogaEdge.BOTTOM;
}
throw new IllegalArgumentException("Given unknown edge index: " + i);
}
/**
* @param values values pertaining to {@link YogaEdge}s
* @return whether the values are equal for each edge
*/
static boolean equalValues(int[] values) {
if (values.length != EDGE_COUNT) {
throw new IllegalArgumentException("Given wrongly sized array");
}
int lastValue = values[0];
for (int i = 1, length = values.length; i < length; ++i) {
if (lastValue != values[i]) {
return false;
}
}
return true;
}
private static void setEdgeValue(int[] edges, YogaEdge edge, int value) {
switch(edge) {
case ALL:
for (int i = 0; i < EDGE_COUNT; ++i) {
edges[i] = value;
}
break;
case VERTICAL:
edges[EDGE_TOP] = value;
edges[EDGE_BOTTOM] = value;
break;
case HORIZONTAL:
edges[EDGE_LEFT] = value;
edges[EDGE_RIGHT] = value;
break;
case LEFT:
case TOP:
case RIGHT:
case BOTTOM:
case START:
case END:
edges[edgeIndex(edge)] = value;
break;
}
}
private static int edgeIndex(YogaEdge edge) {
switch(edge) {
case START:
case LEFT:
return EDGE_LEFT;
case TOP:
return EDGE_TOP;
case END:
case RIGHT:
return EDGE_RIGHT;
case BOTTOM:
return EDGE_BOTTOM;
case HORIZONTAL:
case VERTICAL:
case ALL:
}
throw new IllegalArgumentException("Given unsupported edge " + edge.name());
}
public static clreplaced Builder {
private static final int MAX_PATH_EFFECTS = 2;
private final Border mBorder;
@Nullable
private ResourceResolver mResourceResolver;
private PathEffect[] mPathEffects = new PathEffect[MAX_PATH_EFFECTS];
private int mNumPathEffects;
Builder(ComponentContext context) {
mResourceResolver = context.getResourceResolver();
mBorder = new Border();
}
/**
* Specifies a width for a specific edge
*
* <p>Note: Having a border effect with varying widths per edge is currently not supported
*
* @param edge The {@link YogaEdge} that will have its width modified
* @param width The desired width in raw pixels
*/
public Builder widthPx(YogaEdge edge, @Px int width) {
checkNotBuilt();
mBorder.setEdgeWidth(edge, width);
return this;
}
/**
* Specifies a width for a specific edge
*
* <p>Note: Having a border effect with varying widths per edge is currently not supported
*
* @param edge The {@link YogaEdge} that will have its width modified
* @param width The desired width in density independent pixels
*/
public Builder widthDip(YogaEdge edge, @Dimension(unit = DP) float width) {
checkNotBuilt();
return widthPx(edge, mResourceResolver.dipsToPixels(width));
}
/**
* Specifies a width for a specific edge
*
* <p>Note: Having a border effect with varying widths per edge is currently not supported
*
* @param edge The {@link YogaEdge} that will have its width modified
* @param widthRes The desired width resource to resolve
*/
public Builder widthRes(YogaEdge edge, @DimenRes int widthRes) {
checkNotBuilt();
return widthPx(edge, mResourceResolver.resolveDimenSizeRes(widthRes));
}
/**
* Specifies a width for a specific edge
*
* <p>Note: Having a border effect with varying widths per edge is currently not supported
*
* @param edge The {@link YogaEdge} that will have its width modified
* @param attrId The attribute to resolve a width value from
*/
public Builder widthAttr(YogaEdge edge, @AttrRes int attrId) {
checkNotBuilt();
return widthAttr(edge, attrId, 0);
}
/**
* Specifies a width for a specific edge
*
* <p>Note: Having a border effect with varying widths per edge is currently not supported
*
* @param edge The {@link YogaEdge} that will have its width modified
* @param attrId The attribute to resolve a width value from
* @param defaultResId Default resource value to utilize if the attribute is not set
*/
public Builder widthAttr(YogaEdge edge, @AttrRes int attrId, @DimenRes int defaultResId) {
checkNotBuilt();
return widthPx(edge, mResourceResolver.resolveDimenSizeAttr(attrId, defaultResId));
}
/**
* Specifies the border radius for all corners
*
* @param radius The desired border radius for all corners
*/
public Builder radiusPx(@Px int radius) {
checkNotBuilt();
for (int i = 0; i < RADIUS_COUNT; ++i) {
mBorder.mRadius[i] = radius;
}
return this;
}
/**
* Specifies the border radius for all corners
*
* @param radius The desired border radius for all corners
*/
public Builder radiusDip(@Dimension(unit = DP) float radius) {
checkNotBuilt();
return radiusPx(mResourceResolver.dipsToPixels(radius));
}
/**
* Specifies the border radius for all corners
*
* @param radiusRes The resource id to retrieve the border radius value from
*/
public Builder radiusRes(@DimenRes int radiusRes) {
checkNotBuilt();
return radiusPx(mResourceResolver.resolveDimenSizeRes(radiusRes));
}
/**
* Specifies the border radius for all corners
*
* @param attrId The attribute id to retrieve the border radius value from
*/
public Builder radiusAttr(@AttrRes int attrId) {
return radiusAttr(attrId, 0);
}
/**
* Specifies the border radius for all corners
*
* @param attrId The attribute id to retrieve the border radius value from
* @param defaultResId Default resource to utilize if the attribute is not set
*/
public Builder radiusAttr(@AttrRes int attrId, @DimenRes int defaultResId) {
checkNotBuilt();
return radiusPx(mResourceResolver.resolveDimenSizeAttr(attrId, defaultResId));
}
/**
* Specifies the border radius for the given corner
*
* @param corner The {@link Corner} to specify the radius of
* @param radius The desired radius
*/
public Builder radiusPx(@Corner int corner, @Px int radius) {
checkNotBuilt();
if (corner < 0 || corner >= RADIUS_COUNT) {
throw new IllegalArgumentException("Given invalid corner: " + corner);
}
mBorder.mRadius[corner] = radius;
return this;
}
/**
* Specifies the border radius for the given corner
*
* @param corner The {@link Corner} to specify the radius of
* @param radius The desired radius
*/
public Builder radiusDip(@Corner int corner, @Dimension(unit = DP) float radius) {
checkNotBuilt();
return radiusPx(corner, mResourceResolver.dipsToPixels(radius));
}
/**
* Specifies the border radius for the given corner
*
* @param corner The {@link Corner} to specify the radius of
* @param res The desired dimension resource to use for the radius
*/
public Builder radiusRes(@Corner int corner, @DimenRes int res) {
checkNotBuilt();
return radiusPx(corner, mResourceResolver.resolveDimenSizeRes(res));
}
/**
* Specifies the border radius for the given corner
*
* @param corner The {@link Corner} to specify the radius of
* @param attrId The attribute ID to retrieve the radius from
* @param defaultResId Default resource ID to use if the attribute is not set
*/
public Builder radiusAttr(@Corner int corner, @AttrRes int attrId, @DimenRes int defaultResId) {
checkNotBuilt();
return radiusPx(corner, mResourceResolver.resolveDimenSizeAttr(attrId, defaultResId));
}
/**
* Specifies a color for a specific edge
*
* @param edge The {@link YogaEdge} that will have its color modified
* @param color The raw color value to use
*/
public Builder color(YogaEdge edge, @ColorInt int color) {
checkNotBuilt();
mBorder.setEdgeColor(edge, color);
return this;
}
/**
* Specifies a color for a specific edge
*
* @param edge The {@link YogaEdge} that will have its color modified
* @param colorRes The color resource to use
*/
public Builder colorRes(YogaEdge edge, @ColorRes int colorRes) {
checkNotBuilt();
return color(edge, mResourceResolver.resolveColorRes(colorRes));
}
/**
* Applies a dash effect to the border
*
* <p>Specifying two effects will compose them where the first specified effect acts as the
* outer effect and the second acts as the inner path effect, e.g. outer(inner(path))
*
* @param intervals Must be even-sized >= 2. Even indices specify "on" intervals and odd indices
* specify "off" intervals
* @param phase Offset into the given intervals
*/
public Builder dashEffect(float[] intervals, float phase) {
checkNotBuilt();
checkEffectCount();
mPathEffects[mNumPathEffects++] = new DashPathEffect(intervals, phase);
return this;
}
/**
* Applies a corner effect to the border
*
* @deprecated Please use {@link #radiusPx(int)} instead
* @param radius The amount to round sharp angles when drawing the border
*/
@Deprecated
public Builder cornerEffect(float radius) {
checkNotBuilt();
if (radius < 0f) {
throw new IllegalArgumentException("Can't have a negative radius value");
}
radiusPx(Math.round(radius));
return this;
}
/**
* Applies a discrete effect to the border
*
* <p>Specifying two effects will compose them where the first specified effect acts as the
* outer effect and the second acts as the inner path effect, e.g. outer(inner(path))
*
* @param segmentLength Length of line segments
* @param deviation Maximum amount of deviation. Utilized value is random in the range
* [-deviation, deviation]
*/
public Builder discreteEffect(float segmentLength, float deviation) {
checkNotBuilt();
checkEffectCount();
mPathEffects[mNumPathEffects++] = new DiscretePathEffect(segmentLength, deviation);
return this;
}
/**
* Applies a path dash effect to the border
*
* <p>Specifying two effects will compose them where the first specified effect acts as the
* outer effect and the second acts as the inner path effect, e.g. outer(inner(path))
*
* @param shape The path to stamp along
* @param advance The spacing between each stamp
* @param phase Amount to offset before the first stamp
* @param style How to transform the shape at each position
*/
public Builder pathDashEffect(Path shape, float advance, float phase, PathDashPathEffect.Style style) {
checkNotBuilt();
checkEffectCount();
mPathEffects[mNumPathEffects++] = new PathDashPathEffect(shape, advance, phase, style);
return this;
}
public Border build() {
checkNotBuilt();
mResourceResolver = null;
if (mNumPathEffects == MAX_PATH_EFFECTS) {
mBorder.mPathEffect = new ComposePathEffect(mPathEffects[0], mPathEffects[1]);
} else if (mNumPathEffects > 0) {
mBorder.mPathEffect = mPathEffects[0];
}
if (mBorder.mPathEffect != null && !Border.equalValues(mBorder.mEdgeWidths)) {
throw new IllegalArgumentException("Borders do not currently support different widths with a path effect");
}
return mBorder;
}
private void checkNotBuilt() {
if (mResourceResolver == null) {
throw new IllegalStateException("This builder has already been disposed / built!");
}
}
private void checkEffectCount() {
if (mNumPathEffects >= MAX_PATH_EFFECTS) {
throw new IllegalArgumentException("You cannot specify more than 2 effects to compose");
}
}
}
@Override
public boolean isEquivalentTo(@Nullable Border other) {
if (this == other) {
return true;
}
if (other == null) {
return false;
}
return Arrays.equals(mRadius, other.mRadius) && Arrays.equals(mEdgeWidths, other.mEdgeWidths) && Arrays.equals(mEdgeColors, other.mEdgeColors) && mPathEffect == other.mPathEffect;
}
}
19
Source : LineStyle.java
with Apache License 2.0
from didi
with Apache License 2.0
from didi
public clreplaced LineStyle implements IStyle {
private float width = -1;
private int color = -1;
private boolean isFill;
private PathEffect effect = new PathEffect();
private static float defaultLineSize = 2f;
private static int defaultLineColor = Color.parseColor("#e6e6e6");
public LineStyle() {
}
public LineStyle(float width, int color) {
this.width = width;
this.color = color;
}
public LineStyle(Context context, float dp, int color) {
this.width = DensityUtils.dp2px(context, dp);
this.color = color;
}
public static void setDefaultLineSize(float width) {
defaultLineSize = width;
}
public static void setDefaultLineSize(Context context, float dp) {
defaultLineSize = DensityUtils.dp2px(context, dp);
}
public static void setDefaultLineColor(int color) {
defaultLineColor = color;
}
public float getWidth() {
if (width == -1) {
return defaultLineSize;
}
return width;
}
public LineStyle setWidth(float width) {
this.width = width;
return this;
}
public LineStyle setWidth(Context context, int dp) {
this.width = DensityUtils.dp2px(context, dp);
return this;
}
public int getColor() {
if (color == -1) {
return defaultLineColor;
}
return color;
}
public boolean isFill() {
return isFill;
}
public LineStyle setFill(boolean fill) {
isFill = fill;
return this;
}
public LineStyle setColor(int color) {
this.color = color;
return this;
}
public LineStyle setEffect(PathEffect effect) {
this.effect = effect;
return this;
}
@Override
public void fillPaint(Paint paint) {
paint.setColor(getColor());
paint.setStyle(isFill ? Paint.Style.FILL : Paint.Style.STROKE);
paint.setStrokeWidth(getWidth());
paint.setPathEffect(effect);
}
}
19
Source : LineStyle.java
with Apache License 2.0
from didi
with Apache License 2.0
from didi
public LineStyle setEffect(PathEffect effect) {
this.effect = effect;
return this;
}
19
Source : AnimationRouteHelper.java
with MIT License
from amalChandran
with MIT License
from amalChandran
public void setUpdate1(float update) {
PathEffect effect = new DashPathEffect(dashValue, -length * update);
overlayPolyline.getTopLayerPaint().setPathEffect(effect);
routeOverlayView.invalidate();
}
19
Source : AnimationRouteHelper.java
with MIT License
from amalChandran
with MIT License
from amalChandran
public void setUpdate(float update) {
PathEffect effect = new DashPathEffect(dashValue, length * update);
overlayPolyline.getTopLayerPaint().setPathEffect(effect);
routeOverlayView.invalidate();
}
19
Source : AnimationArcHelper.java
with MIT License
from amalChandran
with MIT License
from amalChandran
public void setUpdate(float update) {
PathEffect effect = new DashPathEffect(arcdDashValue, arcLength * update);
overlayPolyline.getTopLayerPaint().setPathEffect(effect);
PathEffect shadowEffect = new DashPathEffect(shadowDashValue, shadowLength * update);
overlayPolyline.getShadowPaint().setPathEffect(shadowEffect);
mRouteOverlayView.invalidate();
}
19
Source : AnimationArcHelper.java
with MIT License
from amalChandran
with MIT License
from amalChandran
public void setUpdate1(float update) {
PathEffect effect = new DashPathEffect(arcdDashValue, -arcLength * update);
overlayPolyline.getTopLayerPaint().setPathEffect(effect);
mRouteOverlayView.invalidate();
}
18
Source : StandLinesChart.java
with Apache License 2.0
from openXu
with Apache License 2.0
from openXu
private void drawAxisLine(Canvas canvas, AxisLine axisLine) {
if (axisLine.type == AxisLineType.SOLID) {
// 实线
paint.setStrokeWidth(axisLine.lineWidth);
paint.setColor(axisLine.lineColor);
canvas.drawLine(axisLine.pointStart.x, axisLine.pointStart.y, axisLine.pointEnd.x, axisLine.pointEnd.y, paint);
}
if (axisLine.type == AxisLineType.DASHE) {
// 虚线
paintEffect.setStrokeWidth(axisLine.lineWidth);
paintEffect.setColor(axisLine.lineColor);
Path path = new Path();
path.moveTo(axisLine.pointStart.x, axisLine.pointStart.y);
path.lineTo(axisLine.pointEnd.x, axisLine.pointEnd.y);
PathEffect effects = new DashPathEffect(new float[] { 15, 8, 15, 8 }, 0);
paintEffect.setPathEffect(effects);
canvas.drawPath(path, paintEffect);
}
}
18
Source : LineChartView.java
with Apache License 2.0
from nicolite
with Apache License 2.0
from nicolite
private void initPaint() {
// 虚线
bgLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bgLinePaint.setStyle(Paint.Style.STROKE);
bgLinePaint.setColor(Color.parseColor("#ADADAD"));
bgLinePaint.setStrokeWidth(2);
PathEffect effects = new DashPathEffect(new float[] { 13, 13 }, 5);
bgLinePaint.setPathEffect(effects);
// 发光线一号
BlurMaskFilter bmf = new BlurMaskFilter(4, BlurMaskFilter.Blur.SOLID);
linePaint1 = new Paint(Paint.ANTI_ALIAS_FLAG);
linePaint1.setStyle(Paint.Style.STROKE);
linePaint1.setColor(Color.parseColor("#fdeb6b"));
linePaint1.setStrokeWidth(lineWidth);
linePaint1.setMaskFilter(bmf);
// 发光线2号
linePaint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
linePaint2.setStyle(Paint.Style.STROKE);
linePaint2.setColor(Color.parseColor("#6effb6"));
linePaint2.setStrokeWidth(lineWidth);
linePaint2.setMaskFilter(bmf);
// 标题
replacedlePaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
replacedlePaint.setTextSize(sp14);
replacedlePaint.setColor(Color.parseColor("#adadad"));
// 数值一号
valuePaint1 = new TextPaint(Paint.ANTI_ALIAS_FLAG);
valuePaint1.setTextSize(sp10);
valuePaint1.setColor(Color.parseColor(COLOR_1));
// 数值二号
valuePaint2 = new TextPaint(Paint.ANTI_ALIAS_FLAG);
valuePaint2.setTextSize(sp10);
valuePaint2.setColor(Color.parseColor(COLOR_2));
// 文本
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
textPaint.setTextSize(sp10);
textPaint.setColor(Color.WHITE);
// 标注
labelPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
labelPaint.setTextSize(sp10);
labelPaint.setColor(Color.parseColor("#adadad"));
// 圆点
circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
circlePaint.setStyle(Paint.Style.FILL);
circlePaint.setColor(Color.WHITE);
}
18
Source : DashedLineView.java
with BSD 3-Clause "New" or "Revised" License
from Kommunicate-io
with BSD 3-Clause "New" or "Revised" License
from Kommunicate-io
public clreplaced DashedLineView extends View {
private float density;
private Paint paint;
private Path path;
private PathEffect effects;
private String dashColor = "#BEBBBB";
private float dashWidth = DimensionsUtils.convertDpToPixel(4);
private float dashSpacing = DimensionsUtils.convertDpToPixel(2);
public DashedLineView(Context context) {
super(context);
init(context);
}
public DashedLineView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public DashedLineView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
density = context.getResources().getDisplayMetrics().density;
paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(density * 4);
// set your own color
paint.setColor(Color.parseColor(dashColor));
path = new Path();
// array is ON and OFF distances in px (4px line then 2px space)
effects = new DashPathEffect(new float[] { dashWidth, dashSpacing, dashWidth, dashSpacing }, 0);
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
paint.setPathEffect(effects);
int measuredHeight = getMeasuredHeight();
int measuredWidth = getMeasuredWidth();
if (measuredHeight <= measuredWidth) {
// horizontal
path.moveTo(0, 0);
path.lineTo(measuredWidth, 0);
canvas.drawPath(path, paint);
} else {
// vertical
path.moveTo(0, 0);
path.lineTo(0, measuredHeight);
canvas.drawPath(path, paint);
}
}
}
18
Source : OldCreditSesameView.java
with Apache License 2.0
from HotBitmapGG
with Apache License 2.0
from HotBitmapGG
/**
* 初始化
*/
private void init() {
// 设置默认宽高值
defaultSize = dp2px(250);
// 设置图片线条的抗锯齿
mPaintFlagsDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
// 最外层圆环渐变画笔设置
mGradientRingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
// 设置圆环渐变色渲染
mGradientRingPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
float[] position = { 0.1f, 0.3f, 0.8f };
Shader mShader = new SweepGradient(width / 2, radius, mColors, position);
mGradientRingPaint.setShader(mShader);
mGradientRingPaint.setStrokeCap(Paint.Cap.ROUND);
mGradientRingPaint.setStyle(Paint.Style.STROKE);
mGradientRingPaint.setStrokeWidth(40);
// 最外层圆环大小刻度画笔设置
mSmallCalibrationPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mSmallCalibrationPaint.setColor(Color.WHITE);
mSmallCalibrationPaint.setStyle(Paint.Style.STROKE);
mSmallCalibrationPaint.setStrokeWidth(1);
mBigCalibrationPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mBigCalibrationPaint.setColor(Color.WHITE);
mBigCalibrationPaint.setStyle(Paint.Style.STROKE);
mBigCalibrationPaint.setStrokeWidth(4);
// 中间圆环画笔设置
mMiddleRingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mMiddleRingPaint.setStyle(Paint.Style.STROKE);
mMiddleRingPaint.setStrokeCap(Paint.Cap.ROUND);
mMiddleRingPaint.setStrokeWidth(5);
mMiddleRingPaint.setColor(GRAY_COLOR);
// 内层圆环画笔设置
mInnerRingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mInnerRingPaint.setStyle(Paint.Style.STROKE);
mInnerRingPaint.setStrokeCap(Paint.Cap.ROUND);
mInnerRingPaint.setStrokeWidth(4);
mInnerRingPaint.setColor(GRAY_COLOR);
PathEffect mPathEffect = new DashPathEffect(new float[] { 5, 5, 5, 5 }, 1);
mInnerRingPaint.setPathEffect(mPathEffect);
// 外层圆环文本画笔设置
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setColor(GRAY_COLOR);
mTextPaint.setTextSize(30);
// 中间文字画笔设置
mCenterTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mCenterTextPaint.setTextAlign(Paint.Align.CENTER);
// 中间圆环进度画笔设置
mMiddleProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mMiddleProgressPaint.setColor(GREEN_COLOR);
mMiddleProgressPaint.setStrokeCap(Paint.Cap.ROUND);
mMiddleProgressPaint.setStrokeWidth(5);
mMiddleProgressPaint.setStyle(Paint.Style.STROKE);
// 指针图片画笔
mPointerBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPointerBitmapPaint.setColor(GREEN_COLOR);
// 获取指针图片
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_pointer);
mBitmapHeight = mBitmap.getHeight();
mBitmapWidth = mBitmap.getWidth();
}
17
Source : RecyclerViewItemDecoration.java
with GNU General Public License v3.0
from z-chu
with GNU General Public License v3.0
from z-chu
/**
* draw vertival decoration
*
* @param c
* @param parent
*/
private void drawVertical(Canvas c, RecyclerView parent) {
int childrenCount = parent.getChildCount();
if (mDrawableRid != 0) {
if (mFirstLineVisible) {
View childView = parent.getChildAt(0);
int myX = childView.getLeft();
if (hasNinePatch) {
Rect rect = new Rect(myX - mCurrentThickness, mPaddingStart, myX, parent.getHeight() - mPaddingEnd);
mNinePatch.draw(c, rect);
} else {
c.drawBitmap(mBmp, myX - mCurrentThickness, mPaddingStart, mPaint);
}
}
for (int i = 0; i < childrenCount; i++) {
if (!mLastLineVisible && i == childrenCount - 1)
break;
View childView = parent.getChildAt(i);
int myX = childView.getRight();
if (hasNinePatch) {
Rect rect = new Rect(myX, mPaddingStart, myX + mCurrentThickness, parent.getHeight() - mPaddingEnd);
mNinePatch.draw(c, rect);
} else {
c.drawBitmap(mBmp, myX, mPaddingStart, mPaint);
}
}
} else {
boolean isPureLine = isPureLine();
if (!isPureLine) {
PathEffect effects = new DashPathEffect(new float[] { 0, 0, mDashWidth, mThickness }, mDashGap);
mPaint.setPathEffect(effects);
}
if (mFirstLineVisible) {
View childView = parent.getChildAt(0);
int myX = childView.getLeft() - mThickness / 2;
if (isPureLine) {
c.drawLine(myX, mPaddingStart, myX, parent.getHeight() - mPaddingEnd, mPaint);
} else {
Path path = new Path();
path.moveTo(myX, mPaddingStart);
path.lineTo(myX, parent.getHeight() - mPaddingEnd);
c.drawPath(path, mPaint);
}
}
for (int i = 0; i < childrenCount; i++) {
if (!mLastLineVisible && i == childrenCount - 1)
break;
View childView = parent.getChildAt(i);
int myX = childView.getRight() + mThickness / 2;
if (isPureLine) {
c.drawLine(myX, mPaddingStart, myX, parent.getHeight() - mPaddingEnd, mPaint);
} else {
Path path = new Path();
path.moveTo(myX, mPaddingStart);
path.lineTo(myX, parent.getHeight() - mPaddingEnd);
c.drawPath(path, mPaint);
}
}
}
}
17
Source : RecyclerViewItemDecoration.java
with GNU General Public License v3.0
from z-chu
with GNU General Public License v3.0
from z-chu
/**
* draw horizontal decoration
*
* @param c
* @param parent
*/
private void drawHorinzontal(Canvas c, RecyclerView parent) {
int childrenCount = parent.getChildCount();
if (mDrawableRid != 0) {
if (mFirstLineVisible) {
View childView = parent.getChildAt(0);
int myY = childView.getTop();
if (hasNinePatch) {
Rect rect = new Rect(mPaddingStart, myY - mCurrentThickness, parent.getWidth() - mPaddingEnd, myY);
mNinePatch.draw(c, rect);
} else {
c.drawBitmap(mBmp, mPaddingStart, myY - mCurrentThickness, mPaint);
}
}
for (int i = 0; i < childrenCount; i++) {
if (!mLastLineVisible && i == childrenCount - 1)
break;
View childView = parent.getChildAt(i);
int myY = childView.getBottom();
if (hasNinePatch) {
Rect rect = new Rect(mPaddingStart, myY, parent.getWidth() - mPaddingEnd, myY + mCurrentThickness);
mNinePatch.draw(c, rect);
} else {
c.drawBitmap(mBmp, mPaddingStart, myY, mPaint);
}
}
} else {
boolean isPureLine = isPureLine();
if (!isPureLine) {
PathEffect effects = new DashPathEffect(new float[] { 0, 0, mDashWidth, mThickness }, mDashGap);
mPaint.setPathEffect(effects);
}
if (mFirstLineVisible) {
View childView = parent.getChildAt(0);
int myY = childView.getTop() - mThickness / 2;
if (isPureLine) {
c.drawLine(mPaddingStart, myY, parent.getWidth() - mPaddingEnd, myY, mPaint);
} else {
Path path = new Path();
path.moveTo(mPaddingStart, myY);
path.lineTo(parent.getWidth() - mPaddingEnd, myY);
c.drawPath(path, mPaint);
}
}
for (int i = 0; i < childrenCount; i++) {
if (!mLastLineVisible && i == childrenCount - 1)
break;
View childView = parent.getChildAt(i);
int myY = childView.getBottom() + mThickness / 2;
if (isPureLine) {
c.drawLine(mPaddingStart, myY, parent.getWidth() - mPaddingEnd, myY, mPaint);
} else {
Path path = new Path();
path.moveTo(mPaddingStart, myY);
path.lineTo(parent.getWidth() - mPaddingEnd, myY);
c.drawPath(path, mPaint);
}
}
}
}
17
Source : CSSBoxModelView.java
with Apache License 2.0
from weexteam
with Apache License 2.0
from weexteam
/**
* Description:
* 绘制css盒模型
* Created by rowandjj(chuyi)<br/>
*/
public clreplaced CSSBoxModelView extends View {
private static final int COLOR_MARGIN = 0xBAFACC9E;
private static final int COLOR_BORDER = 0xBAFCDC9B;
private static final int COLOR_PADDING = 0xBAC3CE8A;
private static final int COLOR_CONTENT = 0xBA12B6C1;
private static final int COLOR_TEXT = 0xFFFFFFFF;
private static final String TEXT_MARGIN = "margin";
private static final String TEXT_BORDER = "border";
private static final String TEXT_PADDING = "padding";
private static final String TEXT_UNKNOWN = "?";
private static final String TEXT_ZERO = "0";
private static final String TEXT_NULL = "-";
private final float DEFAULT_VIEW_HEIGHT = ViewUtils.dp2px(getContext(), 160);
private final float DEFAULT_VIEW_WIDTH = ViewUtils.dp2px(getContext(), 200);
private final float DEFAULT_BOX_GAP = ViewUtils.dp2px(getContext(), 45);
private float mViewMinWidth = DEFAULT_VIEW_WIDTH;
private float mViewMinHeight = DEFAULT_VIEW_HEIGHT;
private Paint mShapePaint;
private Paint mTextPaint;
private RectF mOuterBounds;
private RectF mBorderBounds;
private RectF mPaddingBounds;
private RectF mContentBounds;
private float mTextOffsetX;
private float mTextOffsetY;
private PathEffect mPathEffect;
private Rect mCachedTextBounds;
// 动态文案
private String mMarginLeftText;
private String mMarginTopText;
private String mMarginRightText;
private String mMarginBottomText;
private String mPaddingLeftText;
private String mPaddingTopText;
private String mPaddingRightText;
private String mPaddingBottomText;
private String mBorderLeftText;
private String mBorderTopText;
private String mBorderRightText;
private String mBorderBottomText;
private String mWidthText;
private String mHeightText;
private boolean isNative = false;
public CSSBoxModelView(Context context) {
super(context);
init();
}
public CSSBoxModelView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CSSBoxModelView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mShapePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mShapePaint.setStrokeWidth(ViewUtils.dp2px(getContext(), 1));
mShapePaint.setDither(true);
mShapePaint.setColor(COLOR_TEXT);
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setDither(true);
mTextPaint.setTextSize(ViewUtils.sp2px(getContext(), 12));
mTextPaint.setColor(COLOR_TEXT);
mTextPaint.setTypeface(Typeface.DEFAULT);
Paint.FontMetrics metrics = mTextPaint.getFontMetrics();
mTextOffsetY = -(metrics.descent + metrics.ascent) / 2.0f;
mTextOffsetX = (metrics.descent - metrics.ascent) / 2.0f;
mCachedTextBounds = new Rect();
mViewMinWidth = DEFAULT_VIEW_WIDTH;
mViewMinHeight = DEFAULT_VIEW_HEIGHT;
mPathEffect = new DashPathEffect(new float[] { 5, 5, 5, 5 }, 1);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
float width = Math.max(getWidth(), mViewMinWidth);
float height = Math.max(getHeight(), mViewMinHeight);
mOuterBounds = new RectF(getPaddingLeft(), getPaddingTop(), getPaddingLeft() + width, getPaddingTop() + height);
mBorderBounds = new RectF(getPaddingLeft(), getPaddingTop(), getPaddingLeft() + width - DEFAULT_BOX_GAP, getPaddingTop() + 3 * height / 4.0f);
mPaddingBounds = new RectF(getPaddingLeft(), getPaddingTop(), getPaddingLeft() + width - DEFAULT_BOX_GAP * 2, getPaddingTop() + height / 2.0f);
mContentBounds = new RectF(getPaddingLeft(), getPaddingTop(), getPaddingLeft() + width - DEFAULT_BOX_GAP * 3, getPaddingTop() + height / 4.0f);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = (int) (mViewMinWidth + getPaddingLeft() + getPaddingRight());
int height = (int) (mViewMinHeight + getPaddingTop() + getPaddingBottom());
setMeasuredDimension(getResolvedSize(width, widthMeasureSpec), getResolvedSize(height, heightMeasureSpec));
}
@Override
protected void onDraw(Canvas canvas) {
// step1 绘制背景
mShapePaint.setStyle(Paint.Style.FILL);
// 最外层背景
canvas.save();
mShapePaint.setColor(COLOR_MARGIN);
// 使用clipRect避免重绘
canvas.clipRect((mOuterBounds.width() - mBorderBounds.width()) / 2.0f, (mOuterBounds.height() - mBorderBounds.height()) / 2.0f, (mOuterBounds.width() + mBorderBounds.width()) / 2.0f, (mOuterBounds.height() + mBorderBounds.height()) / 2.0f, Region.Op.DIFFERENCE);
canvas.drawRect(mOuterBounds, mShapePaint);
canvas.restore();
// border背景
canvas.save();
canvas.translate((mOuterBounds.width() - mBorderBounds.width()) / 2.0f, (mOuterBounds.height() - mBorderBounds.height()) / 2.0f);
mShapePaint.setColor(COLOR_BORDER);
canvas.clipRect((mBorderBounds.width() - mPaddingBounds.width()) / 2.0f, (mBorderBounds.height() - mPaddingBounds.height()) / 2.0f, (mBorderBounds.width() + mPaddingBounds.width()) / 2.0f, (mBorderBounds.height() + mPaddingBounds.height()) / 2.0f, Region.Op.DIFFERENCE);
canvas.drawRect(mBorderBounds, mShapePaint);
canvas.restore();
// padding背景
canvas.save();
canvas.translate((mOuterBounds.width() - mPaddingBounds.width()) / 2.0f, (mOuterBounds.height() - mPaddingBounds.height()) / 2.0f);
mShapePaint.setColor(COLOR_PADDING);
canvas.clipRect((mPaddingBounds.width() - mContentBounds.width()) / 2.0f, (mPaddingBounds.height() - mContentBounds.height()) / 2.0f, (mPaddingBounds.width() + mContentBounds.width()) / 2.0f, (mPaddingBounds.height() + mContentBounds.height()) / 2.0f, Region.Op.DIFFERENCE);
canvas.drawRect(mPaddingBounds, mShapePaint);
canvas.restore();
// content背景
canvas.save();
canvas.translate((mOuterBounds.width() - mContentBounds.width()) / 2.0f, (mOuterBounds.height() - mContentBounds.height()) / 2.0f);
mShapePaint.setColor(COLOR_CONTENT);
canvas.drawRect(mContentBounds, mShapePaint);
canvas.restore();
// step2 绘制框
mShapePaint.setColor(COLOR_TEXT);
mShapePaint.setStyle(Paint.Style.STROKE);
mShapePaint.setPathEffect(mPathEffect);
canvas.save();
// 最外层框
canvas.drawRect(mOuterBounds, mShapePaint);
// border框
canvas.translate((mOuterBounds.width() - mBorderBounds.width()) / 2.0f, (mOuterBounds.height() - mBorderBounds.height()) / 2.0f);
mShapePaint.setPathEffect(null);
canvas.drawRect(mBorderBounds, mShapePaint);
// padding框
canvas.translate((mBorderBounds.width() - mPaddingBounds.width()) / 2.0f, (mBorderBounds.height() - mPaddingBounds.height()) / 2.0f);
mShapePaint.setPathEffect(mPathEffect);
canvas.drawRect(mPaddingBounds, mShapePaint);
// content框
canvas.translate((mPaddingBounds.width() - mContentBounds.width()) / 2.0f, (mPaddingBounds.height() - mContentBounds.height()) / 2.0f);
mShapePaint.setPathEffect(null);
canvas.drawRect(mContentBounds, mShapePaint);
canvas.restore();
// step3 绘制文案
canvas.save();
// 最外层文案
canvas.drawText(TEXT_MARGIN, mTextOffsetX + mOuterBounds.left, (mOuterBounds.height() - mBorderBounds.height()) / 4.0f + mTextOffsetY, mTextPaint);
// margin-left
String tempText = prepareText(mMarginLeftText, TEXT_ZERO);
mTextPaint.getTextBounds(tempText, 0, tempText.length(), mCachedTextBounds);
canvas.drawText(tempText, mOuterBounds.left + (mOuterBounds.width() - mBorderBounds.width()) / 4.0f - mCachedTextBounds.width() / 2.0f, mOuterBounds.top + mOuterBounds.height() / 2.0f + mTextOffsetY, mTextPaint);
// margin-top
tempText = prepareText(mMarginTopText, TEXT_ZERO);
mTextPaint.getTextBounds(tempText, 0, tempText.length(), mCachedTextBounds);
canvas.drawText(tempText, mOuterBounds.left + mOuterBounds.width() / 2.0f - mCachedTextBounds.width() / 2.0f, mOuterBounds.top + (mOuterBounds.height() - mBorderBounds.height()) / 4.0f + mTextOffsetY, mTextPaint);
// margin-right
tempText = prepareText(mMarginRightText, TEXT_ZERO);
mTextPaint.getTextBounds(tempText, 0, tempText.length(), mCachedTextBounds);
canvas.drawText(tempText, mOuterBounds.width() - (mOuterBounds.width() - mBorderBounds.width()) / 4.0f - mCachedTextBounds.width() / 2.0f, mOuterBounds.top + mOuterBounds.height() / 2.0f + mTextOffsetY, mTextPaint);
// margin-bottom
tempText = prepareText(mMarginBottomText, TEXT_ZERO);
mTextPaint.getTextBounds(tempText, 0, tempText.length(), mCachedTextBounds);
canvas.drawText(tempText, mOuterBounds.left + mOuterBounds.width() / 2.0f - mCachedTextBounds.width() / 2.0f, mOuterBounds.bottom - (mOuterBounds.height() - mBorderBounds.height()) / 4.0f + mTextOffsetY, mTextPaint);
// border文案
canvas.translate((mOuterBounds.width() - mBorderBounds.width()) / 2.0f, (mOuterBounds.height() - mBorderBounds.height()) / 2.0f);
canvas.drawText(TEXT_BORDER, mTextOffsetX, (mBorderBounds.height() - mPaddingBounds.height()) / 4.0f + mTextOffsetY, mTextPaint);
// border-left
tempText = prepareText(mBorderLeftText, isNative ? TEXT_NULL : TEXT_ZERO);
mTextPaint.getTextBounds(tempText, 0, tempText.length(), mCachedTextBounds);
canvas.drawText(tempText, mBorderBounds.left + (mBorderBounds.width() - mPaddingBounds.width()) / 4.0f - mCachedTextBounds.width() / 2.0f, mBorderBounds.top + mBorderBounds.height() / 2.0f + mTextOffsetY, mTextPaint);
// border-top
tempText = prepareText(mBorderTopText, isNative ? TEXT_NULL : TEXT_ZERO);
mTextPaint.getTextBounds(tempText, 0, tempText.length(), mCachedTextBounds);
canvas.drawText(tempText, mBorderBounds.left + mBorderBounds.width() / 2.0f - mCachedTextBounds.width() / 2.0f, mBorderBounds.top + (mBorderBounds.height() - mPaddingBounds.height()) / 4.0f + mTextOffsetY, mTextPaint);
// border-right
tempText = prepareText(mBorderRightText, isNative ? TEXT_NULL : TEXT_ZERO);
mTextPaint.getTextBounds(tempText, 0, tempText.length(), mCachedTextBounds);
canvas.drawText(tempText, mBorderBounds.width() - (mBorderBounds.width() - mPaddingBounds.width()) / 4.0f - mCachedTextBounds.width() / 2.0f, mBorderBounds.top + mBorderBounds.height() / 2.0f + mTextOffsetY, mTextPaint);
// border-bottom
tempText = prepareText(mBorderBottomText, isNative ? TEXT_NULL : TEXT_ZERO);
mTextPaint.getTextBounds(tempText, 0, tempText.length(), mCachedTextBounds);
canvas.drawText(tempText, mBorderBounds.left + mBorderBounds.width() / 2.0f - mCachedTextBounds.width() / 2.0f, mBorderBounds.bottom - (mBorderBounds.height() - mPaddingBounds.height()) / 4.0f + mTextOffsetY, mTextPaint);
// padding文案
canvas.translate((mBorderBounds.width() - mPaddingBounds.width()) / 2.0f, (mBorderBounds.height() - mPaddingBounds.height()) / 2.0f);
canvas.drawText(TEXT_PADDING, mTextOffsetX / 2.0f, (mPaddingBounds.height() - mContentBounds.height()) / 4.0f + mTextOffsetY, mTextPaint);
// padding-left
tempText = prepareText(mPaddingLeftText, TEXT_ZERO);
mTextPaint.getTextBounds(tempText, 0, tempText.length(), mCachedTextBounds);
canvas.drawText(tempText, mPaddingBounds.left + (mPaddingBounds.width() - mContentBounds.width()) / 4.0f - mCachedTextBounds.width() / 2.0f, mPaddingBounds.top + mPaddingBounds.height() / 2.0f + mTextOffsetY, mTextPaint);
// padding-top
tempText = prepareText(mPaddingTopText, TEXT_ZERO);
mTextPaint.getTextBounds(tempText, 0, tempText.length(), mCachedTextBounds);
canvas.drawText(tempText, mPaddingBounds.left + mPaddingBounds.width() / 2.0f - mCachedTextBounds.width() / 2.0f, mPaddingBounds.top + (mPaddingBounds.height() - mContentBounds.height()) / 4.0f + mTextOffsetY, mTextPaint);
// padding-right
tempText = prepareText(mPaddingRightText, TEXT_ZERO);
mTextPaint.getTextBounds(tempText, 0, tempText.length(), mCachedTextBounds);
canvas.drawText(tempText, mPaddingBounds.width() - (mPaddingBounds.width() - mContentBounds.width()) / 4.0f - mCachedTextBounds.width() / 2.0f, mPaddingBounds.top + mPaddingBounds.height() / 2.0f + mTextOffsetY, mTextPaint);
// padding-bottom
tempText = prepareText(mPaddingBottomText, TEXT_ZERO);
mTextPaint.getTextBounds(tempText, 0, tempText.length(), mCachedTextBounds);
canvas.drawText(tempText, mPaddingBounds.left + mPaddingBounds.width() / 2.0f - mCachedTextBounds.width() / 2.0f, mPaddingBounds.bottom - (mPaddingBounds.height() - mContentBounds.height()) / 4.0f + mTextOffsetY, mTextPaint);
// content文案
canvas.translate((mPaddingBounds.width() - mContentBounds.width()) / 2.0f, (mPaddingBounds.height() - mContentBounds.height()) / 2.0f);
String content = prepareText(mWidthText, TEXT_UNKNOWN) + " x " + prepareText(mHeightText, TEXT_UNKNOWN);
mTextPaint.getTextBounds(content, 0, content.length(), mCachedTextBounds);
canvas.drawText(content, mContentBounds.width() / 2.0f - mCachedTextBounds.width() / 2.0f, mContentBounds.height() / 2.0f + mTextOffsetY, mTextPaint);
canvas.restore();
}
private String prepareText(@Nullable String text, @NonNull String placeHolder) {
return TextUtils.isEmpty(text) || "0".equals(text) ? placeHolder : text;
}
private int getResolvedSize(int desiredSize, int measureSpec) {
int mode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
int size;
if (mode == MeasureSpec.EXACTLY) {
size = specSize;
} else {
size = desiredSize;
if (mode == MeasureSpec.AT_MOST) {
size = Math.min(desiredSize, specSize);
}
}
return size;
}
public boolean isNative() {
return isNative;
}
public void setNative(boolean aNative) {
isNative = aNative;
}
public String getMarginTopText() {
return mMarginTopText;
}
public void setMarginTopText(String mMarginTopText) {
this.mMarginTopText = mMarginTopText;
}
public String getMarginLeftText() {
return mMarginLeftText;
}
public void setMarginLeftText(String mMarginLeftText) {
this.mMarginLeftText = mMarginLeftText;
}
public String getMarginRightText() {
return mMarginRightText;
}
public void setMarginRightText(String mMarginRightText) {
this.mMarginRightText = mMarginRightText;
}
public String getMarginBottomText() {
return mMarginBottomText;
}
public void setMarginBottomText(String mMarginBottomText) {
this.mMarginBottomText = mMarginBottomText;
}
public String getPaddingLeftText() {
return mPaddingLeftText;
}
public void setPaddingLeftText(String mPaddingLeftText) {
this.mPaddingLeftText = mPaddingLeftText;
}
public String getPaddingTopText() {
return mPaddingTopText;
}
public void setPaddingTopText(String mPaddingTopText) {
this.mPaddingTopText = mPaddingTopText;
}
public String getPaddingRightText() {
return mPaddingRightText;
}
public void setPaddingRightText(String mPaddingRightText) {
this.mPaddingRightText = mPaddingRightText;
}
public String getPaddingBottomText() {
return mPaddingBottomText;
}
public void setPaddingBottomText(String mPaddingBottomText) {
this.mPaddingBottomText = mPaddingBottomText;
}
public String getWidthText() {
return mWidthText;
}
public void setWidthText(String mWidthText) {
this.mWidthText = mWidthText;
}
public String getHeightText() {
return mHeightText;
}
public void setHeightText(String mHeightText) {
this.mHeightText = mHeightText;
}
public String getBorderBottomText() {
return mBorderBottomText;
}
public void setBorderBottomText(String mBorderBottomText) {
this.mBorderBottomText = mBorderBottomText;
}
public String getBorderRightText() {
return mBorderRightText;
}
public void setBorderRightText(String mBorderRightText) {
this.mBorderRightText = mBorderRightText;
}
public String getBorderTopText() {
return mBorderTopText;
}
public void setBorderTopText(String mBorderTopText) {
this.mBorderTopText = mBorderTopText;
}
public String getBorderLeftText() {
return mBorderLeftText;
}
public void setBorderLeftText(String mBorderLeftText) {
this.mBorderLeftText = mBorderLeftText;
}
}
17
Source : MISportsConnectView.java
with MIT License
from sickworm
with MIT License
from sickworm
private void init(Context context) {
mainreplacedlePaint = new Paint();
mainreplacedlePaint.setColor(ContextCompat.getColor(context, R.color.white));
mainreplacedlePaint.setTextAlign(Paint.Align.CENTER);
mainreplacedlePaint.setTextSize(DensityUtils.sp2px(context, MAIN_replacedLE_FONT_SIZE_SP));
mainreplacedleOffsetY = -(mainreplacedlePaint.getFontMetrics().ascent + mainreplacedlePaint.getFontMetrics().descent) / 2;
mainreplacedlePaint.setAntiAlias(true);
circleColor = ContextCompat.getColor(context, R.color.whiteTransparent);
subreplacedlePaint = new Paint();
subreplacedlePaint.setColor(circleColor);
subreplacedlePaint.setTextSize(DensityUtils.sp2px(context, SUB_replacedLE_FONT_SIZE_SP));
subreplacedleOffsetY = DensityUtils.sp2px(context, SUB_replacedLE_FONT_OFFSET_DP);
subreplacedleSeparator = getResources().getString(R.string.sub_replacedle_separator);
subreplacedlePaint.setAntiAlias(true);
bigCirclePaint = new Paint();
bigCirclePaint.setStrokeWidth(DensityUtils.dp2px(context, BIG_CIRCLE_SIZE));
bigCirclePaint.setStyle(Paint.Style.STROKE);
bigCirclePaint.setAntiAlias(true);
blurPaint = new Paint(bigCirclePaint);
blurSize = DensityUtils.dp2px(context, CIRCLE_BLUR_SIZE);
PathEffect pathEffect1 = new CornerPathEffect(DensityUtils.dp2px(getContext(), BIG_CIRCLE_SHAKE_RADIUS));
PathEffect pathEffect2 = new DiscretePathEffect(DensityUtils.dp2px(getContext(), BIG_CIRCLE_SHAKE_RADIUS), DensityUtils.dp2px(getContext(), BIG_CIRCLE_SHAKE_OFFSET));
PathEffect pathEffect = new ComposePathEffect(pathEffect1, pathEffect2);
bigCirclePaint.setPathEffect(pathEffect);
dottedCirclePaint = new Paint();
dottedCirclePaint.setStrokeWidth(DensityUtils.dp2px(context, DOTTED_CIRCLE_WIDTH));
dottedCirclePaint.setColor(ContextCompat.getColor(context, R.color.whiteTransparent));
dottedCirclePaint.setStyle(Paint.Style.STROKE);
float gagPx = DensityUtils.dp2px(context, DOTTED_CIRCLE_GAG);
dottedCirclePaint.setPathEffect(new DashPathEffect(new float[] { gagPx, gagPx }, 0));
dottedCirclePaint.setAntiAlias(true);
solidCirclePaint = new Paint();
solidCirclePaint.setStrokeWidth(DensityUtils.dp2px(context, SOLID_CIRCLE_WIDTH));
solidCirclePaint.setColor(ContextCompat.getColor(context, R.color.white));
solidCirclePaint.setStyle(Paint.Style.STROKE);
solidCirclePaint.setStrokeCap(Paint.Cap.ROUND);
solidCirclePaint.setAntiAlias(true);
dotPaint = new Paint();
dotPaint.setStrokeWidth(DensityUtils.dp2px(context, DOT_SIZE));
dotPaint.setStrokeCap(Paint.Cap.ROUND);
dotPaint.setColor(ContextCompat.getColor(context, R.color.white));
dotPaint.setAntiAlias(true);
backgroundBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.bg_step_law);
// 设置手表 icon 的大小
watchBitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.icon_headview_watch);
float scale = DensityUtils.dp2px(context, WATCH_SIZE) / watchBitmap.getWidth();
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);
watchBitmap = Bitmap.createBitmap(watchBitmap, 0, 0, watchBitmap.getWidth(), watchBitmap.getHeight(), matrix, true);
watchOffset = DensityUtils.sp2px(context, WATCH_OFFSET_DP);
fireworksCircle = new FireworksCircleGraphics(context);
animationThread = new AnimationThread();
animationThread.start();
}
17
Source : LineChart.java
with Apache License 2.0
from openXu
with Apache License 2.0
from openXu
/**
* 绘制焦点
*/
private void drawFocus(Canvas canvas) {
if (null == focusData)
return;
// 绘制竖直虚线
PathEffect effects = new DashPathEffect(new float[] { 8, 5, 8, 5 }, 0);
paintEffect.setStyle(Paint.Style.STROKE);
paintEffect.setStrokeWidth(focusLineSize);
paintEffect.setColor(focusLineColor);
paintEffect.setPathEffect(effects);
Path path = new Path();
path.moveTo(focusData.getPoint().x, rectChart.bottom);
path.lineTo(focusData.getPoint().x, rectChart.top);
canvas.drawPath(path, paintEffect);
// 绘制焦点
// paint.setAntiAlias(true);
// paint.setStyle(Paint.Style.STROKE);
// paint.setStrokeWidth(lineSize);
// paint.setColor(lineColor[0]);
// canvas.drawCircle(point1.x, point1.y, dotRadius, paint);
// paint.setColor(lineColor[1]);
// canvas.drawCircle(point2.x, point2.y, dotRadius, paint);
// 面板
boolean showLeft = focusData.getPoint().x - rectChart.left > (rectChart.right - rectChart.left) / 2;
RectF rect = new RectF(showLeft ? focusData.getPoint().x - foucsRectWidth - 30 : focusData.getPoint().x + 30, rectChart.top, /*+ (rectChart.bottom - rectChart.top)/2 - foucsRectHeight/2*/
showLeft ? focusData.getPoint().x - 30 : focusData.getPoint().x + foucsRectWidth + 30, rectChart.top + foucsRectHeight);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
paint.setAlpha(230);
canvas.drawRect(rect, paint);
// 面板中的文字
// 2020-10-16 06:00
// 零序电流:15.2KW
// A相电流:15.2KW
// A相电流:15.2KW
// A相电流:15.2KW
String text;
float top = rect.top + foucsRectSpace;
for (int i = 0; i < focusPanelText.length; i++) {
if (focusPanelText[i].show) {
paintText.setTextSize(focusPanelText[i].textSize);
paintText.setColor(focusPanelText[i].textColor);
if (i == 0) {
// x轴数据
text = focusData.getData().get(0).getValuex();
} else {
top += foucsRectTextSpace;
text = focusPanelText[i].text + focusData.getData().get(i - 1).getValuey() + yAxisMark.unit;
}
canvas.drawText(text, rect.left + foucsRectSpace, top + FontUtil.getFontLeading(paintText), paintText);
top += FontUtil.getFontHeight(paintText);
}
}
}
17
Source : SshqLinesChart.java
with Apache License 2.0
from openXu
with Apache License 2.0
from openXu
/**
* 绘制X轴方向辅助网格
*/
private void drawGrid(Canvas canvas) {
float yMarkSpace = (rectChart.bottom - rectChart.top) / (yLeft.lableNum - 1);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(lineWidth);
paint.setColor(defColor);
paintEffect.setStyle(Paint.Style.STROKE);
paintEffect.setStrokeWidth(lineWidth);
paintEffect.setColor(defColor);
// canvas.drawLine(rectChart.left, rectChart.top, rectChart.left, rectChart.bottom, paint);
// canvas.drawLine(rectChart.right, rectChart.top, rectChart.right, rectChart.bottom, paint);
PathEffect effects = new DashPathEffect(new float[] { 15, 6, 15, 6 }, 0);
Path path = new Path();
for (int i = 0; i < yLeft.lableNum; i++) {
path.reset();
path.moveTo(rectChart.left, rectChart.bottom - yMarkSpace * i);
path.lineTo(rectChart.right, rectChart.bottom - yMarkSpace * i);
paintEffect.setPathEffect(effects);
canvas.drawPath(path, paintEffect);
}
}
17
Source : QsrdLinesChart.java
with Apache License 2.0
from openXu
with Apache License 2.0
from openXu
/**
* 绘制焦点
*/
private void drawFocus(Canvas canvas) {
if (!onFocus || null == focusData)
return;
// 竖直线
PathEffect effects = new DashPathEffect(new float[] { 15, 10, 15, 10 }, 0);
paintEffect.setStyle(Paint.Style.STROKE);
paintEffect.setStrokeWidth(focusLineSize);
paintEffect.setColor(focusLineColor);
paintEffect.setPathEffect(effects);
Path path = new Path();
path.moveTo(focusData.getPoint().getPoint().x, rectChart.bottom);
path.lineTo(focusData.getPoint().getPoint().x, rectChart.top);
canvas.drawPath(path, paintEffect);
}
17
Source : DashboardView.java
with Apache License 2.0
from openXu
with Apache License 2.0
from openXu
/**
* 仪表盘图表
*/
public clreplaced DashboardView extends BaseChart {
// 总数量
private int total;
// 占比数量
private int progress;
// 动画计算的占比数量
private float animPro;
// 开始角度 (正常情况正下方为90度,这里的30是指正下方向左偏30度,也就是120度)
private int startAngle = 30;
// 虚线宽度
private int dashesSize = DensityUtil.dip2px(getContext(), 20);
// 实线宽度
private int solidSize = DensityUtil.dip2px(getContext(), 9);
// 中心白圈与 实线间隙
private int rSpace1 = DensityUtil.dip2px(getContext(), 25);
// 虚线 实线间隙
private int rSpace2 = DensityUtil.dip2px(getContext(), 4);
// 指针颜色和长度(长度应该比rSpace1小)
private int pointerColor = Color.parseColor("#d55942");
private int pointerRaidus = DensityUtil.dip2px(getContext(), 20);
private int pointerSize = DensityUtil.dip2px(getContext(), 10);
/**
* 文字大小颜色
*/
// 中间文字 (5000亿)
private int centerTextSize = DensityUtil.sp2px(getContext(), 18);
private int centerTextColor = Color.parseColor("#d55942");
// 仪表名称 (量能)
private String nameText = "能量";
private int nameTextSize = DensityUtil.sp2px(getContext(), 20);
private int nameTextColor = Color.parseColor("#dc3929");
// 仪表刻度 (0 一万亿)
private int lableTextSize = DensityUtil.sp2px(getContext(), 18);
private int lableTextColor = Color.parseColor("#e2978a");
private String lableLeft = "0";
private String lableRight = "一万亿";
// 0 一万亿 文字与扇形间距
private int lableSpace = DensityUtil.dip2px(getContext(), 4);
// 渐变色
int[] proColors = new int[] { // 初始颜色
Color.parseColor("#e7ac6a"), // 中间颜色
Color.parseColor("#e47f3f"), // 最终颜色
Color.parseColor("#df422c") };
float[] proPositions = new float[] { 0.3f, .5f, .7f };
SweepGradient proShader;
// 中间灰色边缘渐变色
RadialGradient sideShader;
int[] sideColors = new int[] { // 灰色
Color.parseColor("#b2c2dd"), // 全透明灰色
Color.parseColor("#00b2c2dd") };
// 虚线间隔
PathEffect effects = new DashPathEffect(new float[] { 9, 11, 9, 11 }, 0);
/**
* 计算
*/
// 中间白色圆圈半径
private int centerRaidus;
// 半径
private int chartRaidus;
// 虚线扇形矩形框(位于扇形中心)
protected RectF rectDashes;
// 实线扇形矩形框(位于扇形中心)
protected RectF rectSolid;
// 0 一万亿 lable绘制点
private PointF startPointLeft, startPointRight;
// 量能 绘制点
private PointF startPointName;
public DashboardView(Context context) {
super(context, null);
}
public DashboardView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
}
public DashboardView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public void init(Context context, AttributeSet attrs, int defStyleAttr) {
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(widthMeasureSpec);
LogUtil.i(TAG, "建议宽高:" + widthSize + " * " + heightSize);
// 根据中间文字大小计算白色圆圈半径
paintLabel.setTextSize(centerTextSize);
int textWidth = (int) FontUtil.getFontlength(paintLabel, "100000");
// int textHeight = (int)FontUtil.getFontHeight(paintLabel);
centerRaidus = textWidth / 2 + DensityUtil.dip2px(getContext(), 5);
// 最大半径
chartRaidus = centerRaidus + rSpace1 + solidSize + rSpace2 + dashesSize;
paintLabel.setTextSize(lableTextSize);
LogUtil.d(TAG, "centerRaidus:" + centerRaidus);
LogUtil.d(TAG, "chartRaidus:" + chartRaidus);
// 计算控件宽高
int raidus = chartRaidus;
// 下切面高度 Math.toRadians将角度转换成弧度值
int sectionRaidus = (int) (Math.cos(Math.toRadians(startAngle)) * raidus);
widthSize = getPaddingLeft() + getPaddingRight() + chartRaidus * 2;
heightSize = getPaddingTop() + getPaddingBottom() + chartRaidus + sectionRaidus + lableSpace + (int) FontUtil.getFontHeight(paintLabel);
setMeasuredDimension(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY));
LogUtil.i(TAG, "宽高:" + getMeasuredWidth() + " * " + getMeasuredHeight());
centerPoint = new PointF(getPaddingLeft() + chartRaidus, getPaddingTop() + chartRaidus);
rectChart = new RectF(getPaddingLeft(), getPaddingTop(), getMeasuredWidth() - getPaddingRight(), getPaddingTop() + chartRaidus * 2);
// 计算实线扇形矩形区域-----------------
raidus = centerRaidus + rSpace1 + solidSize / 2;
rectSolid = new RectF(centerPoint.x - raidus, centerPoint.y - raidus, centerPoint.x + raidus, centerPoint.y + raidus);
// 量能 绘制点
startPointName = new PointF(centerPoint.x, rectSolid.bottom);
// 虚线部分--------------------------
raidus = centerRaidus + rSpace1 + solidSize + rSpace2 + dashesSize / 2;
rectDashes = new RectF(centerPoint.x - raidus, centerPoint.y - raidus, centerPoint.x + raidus, centerPoint.y + raidus);
// lable绘制开始和结束点 ----------------
raidus = centerRaidus + rSpace1 + solidSize + rSpace2 + dashesSize;
sectionRaidus = (int) (Math.cos(Math.toRadians(startAngle)) * raidus);
startPointLeft = new PointF((int) (centerPoint.x - Math.sin(Math.toRadians(startAngle)) * raidus), centerPoint.y + sectionRaidus);
startPointRight = new PointF((int) (centerPoint.x + Math.sin(Math.toRadians(startAngle)) * raidus), centerPoint.y + sectionRaidus);
// 渐变色
proShader = new SweepGradient(centerPoint.x, centerPoint.y, proColors, proPositions);
sideShader = new RadialGradient(centerPoint.x, centerPoint.y, centerRaidus + rSpace1, sideColors, new float[] { 0.2f, .75f }, Shader.TileMode.CLAMP);
LogUtil.d(TAG, "centerPoint:" + centerPoint);
LogUtil.d(TAG, "rectChart:" + rectChart);
invalidate();
}
public void setData(int total, int progress) {
if (progress > total)
progress = total;
this.total = total;
this.progress = progress;
startDraw = false;
invalidate();
}
@Override
public void drawDebug(Canvas canvas) {
super.drawDebug(canvas);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.GREEN);
canvas.drawRect(rectChart.left, rectChart.top, rectChart.right, rectChart.bottom, paint);
paint.setColor(Color.BLACK);
canvas.drawRect(rectDashes.left, rectDashes.top, rectDashes.right, rectDashes.bottom, paint);
paint.setColor(Color.GRAY);
canvas.drawRect(rectSolid.left, rectSolid.top, rectSolid.right, rectSolid.bottom, paint);
}
/**
* 绘制图表基本框架
*/
@Override
public void drawDefult(Canvas canvas) {
// 量能
paintLabel.setTextSize(nameTextSize);
paintLabel.setColor(nameTextColor);
canvas.drawText(nameText, startPointName.x - FontUtil.getFontlength(paintLabel, nameText) / 2, startPointName.y - FontUtil.getFontHeight(paintLabel) / 3 * 2 + FontUtil.getFontLeading(paintLabel), paintLabel);
// 0 一万亿
paintLabel.setTextSize(lableTextSize);
paintLabel.setColor(lableTextColor);
canvas.drawText(lableLeft, startPointLeft.x - FontUtil.getFontlength(paintLabel, lableLeft) / 2, startPointLeft.y + lableSpace + FontUtil.getFontLeading(paintLabel), paintLabel);
canvas.drawText(lableRight, startPointRight.x - FontUtil.getFontlength(paintLabel, lableRight) / 2, startPointRight.y + lableSpace + FontUtil.getFontLeading(paintLabel), paintLabel);
// 实线扇形
// 由于渐变色shader是从正东方开始绘制,导致颜色排版错误,这里将画布旋转90度,正下方为0度
canvas.rotate(90, centerPoint.x, centerPoint.y);
paint.setShader(proShader);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(solidSize);
canvas.drawArc(rectSolid, startAngle, 360.0f - startAngle * 2, false, paint);
paint.setShader(null);
// 绘制虚线
paintEffect.setShader(null);
paintEffect.setStyle(Paint.Style.STROKE);
paintEffect.setPathEffect(effects);
paintEffect.setColor(defColor);
paintEffect.setStrokeWidth(dashesSize);
canvas.drawArc(rectDashes, startAngle, 360.0f - startAngle * 2, false, paintEffect);
// 绘制中间灰色边缘
paint.setShader(sideShader);
// paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(rSpace1);
canvas.drawCircle(centerPoint.x, centerPoint.y, centerRaidus + rSpace1 / 2, paint);
paint.setShader(null);
// 中间白色圆圈
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
canvas.drawCircle(centerPoint.x, centerPoint.y, centerRaidus, paint);
// 反转90度还原
canvas.rotate(-90, centerPoint.x, centerPoint.y);
}
/**
* 绘制图表
*/
@Override
public void drawChart(Canvas canvas) {
if (progress > 0) {
// 数量文字
paintLabel.setTextSize(centerTextSize);
paintLabel.setColor(centerTextColor);
String text = ((int) animPro) + "";
canvas.drawText(text, centerPoint.x - FontUtil.getFontlength(paintLabel, text) / 2, centerPoint.y - FontUtil.getFontHeight(paintLabel) + FontUtil.getFontLeading(paintLabel), paintLabel);
text = "亿";
canvas.drawText(text, centerPoint.x - FontUtil.getFontlength(paintLabel, text) / 2, centerPoint.y + DensityUtil.dip2px(getContext(), 2) + FontUtil.getFontLeading(paintLabel), paintLabel);
// 绘制彩色虚线
// 再次寻转90度
canvas.rotate(90, centerPoint.x, centerPoint.y);
float proAngle = (360.0f - startAngle * 2) * (animPro / total * 1.0f);
paintEffect.setStyle(Paint.Style.STROKE);
paintEffect.setPathEffect(effects);
paintEffect.setShader(proShader);
paintEffect.setStrokeWidth(dashesSize);
// 消除由于虚线间隔导致视觉上仪表进度不够的情况,默认多绘制2.5度
canvas.drawArc(rectDashes, startAngle, proAngle < (360.0f - startAngle * 2 - 5) ? proAngle + 2.5f : proAngle, false, paintEffect);
paintEffect.setShader(null);
// 绘制指针
/*画一个实心三角形*/
// 以正东面为0度起点计算指定角度所对应的圆周上的点的坐标:
double asin = Math.toDegrees(Math.asin(pointerSize / 2f / centerRaidus));
float centerArcX1 = centerPoint.x + (float) (centerRaidus * Math.cos(Math.toRadians(startAngle - asin + proAngle)));
float centerArcY1 = centerPoint.y + (float) (centerRaidus * Math.sin(Math.toRadians(startAngle - asin + proAngle)));
// LogUtil.i(TAG, "角度 "+(startAngle-asin+proAngle)+" 弧度:"+Math.toRadians(startAngle-asin+proAngle));
// LogUtil.i(TAG, "cos "+Math.cos(Math.toRadians(startAngle-asin+proAngle)));
// LogUtil.i(TAG, "sin "+Math.sin(Math.toRadians(startAngle-asin+proAngle)));
float endx2 = centerPoint.x + (float) ((pointerRaidus + centerRaidus) * Math.cos(Math.toRadians(startAngle + proAngle)));
float endy2 = centerPoint.y + (float) ((pointerRaidus + centerRaidus) * Math.sin(Math.toRadians(startAngle + proAngle)));
float centerArcX2 = centerPoint.x + (float) (centerRaidus * Math.cos(Math.toRadians(startAngle + asin + proAngle)));
float centerArcY2 = centerPoint.y + (float) (centerRaidus * Math.sin(Math.toRadians(startAngle + asin + proAngle)));
// LogUtil.d(TAG, "角度 "+(startAngle+asin+proAngle)+" 弧度:"+Math.toRadians(startAngle+asin+proAngle));
// LogUtil.d(TAG, "cos "+Math.cos(Math.toRadians(startAngle+asin+proAngle)));
// LogUtil.d(TAG, "sin "+Math.sin(Math.toRadians(startAngle+asin+proAngle)));
Path path2 = new Path();
path2.moveTo(centerArcX1, centerArcY1);
path2.lineTo(endx2, endy2);
path2.lineTo(centerArcX2, centerArcY2);
path2.close();
paint.setColor(pointerColor);
canvas.drawPath(path2, paint);
}
}
/**
* 创建动画
*/
@Override
protected ValueAnimator initAnim() {
anim = ValueAnimator.ofObject(new AngleEvaluator(), 0f, 1.0f);
anim.setInterpolator(new AccelerateDecelerateInterpolator());
return anim;
}
/**
* 动画值变化之后计算数据
*/
@Override
protected void evaluatorData(ValueAnimator animation) {
animPro = (float) animation.getAnimatedValue() * progress;
}
}
17
Source : CustomCurveChart.java
with Apache License 2.0
from liuwan1992
with Apache License 2.0
from liuwan1992
/**
* 初始化数据值和画笔
*/
public void init() {
xPoint = margin + marginX;
yPoint = this.getHeight() - margin;
xScale = (this.getWidth() - 2 * margin - marginX) / (xLabel.length - 1);
yScale = (this.getHeight() - 2 * margin) / (yLabel.length - 1);
paintAxes = new Paint();
paintAxes.setStyle(Paint.Style.STROKE);
paintAxes.setAntiAlias(true);
paintAxes.setDither(true);
paintAxes.setColor(ContextCompat.getColor(getContext(), R.color.color14));
paintAxes.setStrokeWidth(4);
paintCoordinate = new Paint();
paintCoordinate.setStyle(Paint.Style.STROKE);
paintCoordinate.setDither(true);
paintCoordinate.setAntiAlias(true);
paintCoordinate.setColor(ContextCompat.getColor(getContext(), R.color.color14));
paintCoordinate.setTextSize(15);
paintTable = new Paint();
paintTable.setStyle(Paint.Style.STROKE);
paintTable.setAntiAlias(true);
paintTable.setDither(true);
paintTable.setColor(ContextCompat.getColor(getContext(), R.color.color4));
paintTable.setStrokeWidth(2);
paintCurve = new Paint();
paintCurve.setStyle(Paint.Style.STROKE);
paintCurve.setDither(true);
paintCurve.setAntiAlias(true);
paintCurve.setStrokeWidth(3);
PathEffect pathEffect = new CornerPathEffect(25);
paintCurve.setPathEffect(pathEffect);
paintRectF = new Paint();
paintRectF.setStyle(Paint.Style.FILL);
paintRectF.setDither(true);
paintRectF.setAntiAlias(true);
paintRectF.setStrokeWidth(3);
paintValue = new Paint();
paintValue.setStyle(Paint.Style.STROKE);
paintValue.setAntiAlias(true);
paintValue.setDither(true);
paintValue.setColor(ContextCompat.getColor(getContext(), R.color.color1));
paintValue.setTextAlign(Paint.Align.CENTER);
paintValue.setTextSize(15);
}
17
Source : OkView.java
with MIT License
from lihangleo2
with MIT License
from lihangleo2
/**
* Created by leo
* on 2019/11/21.
*/
public clreplaced OkView extends View {
// 绘制一个小圆圈
private Paint paint;
// 绘制打勾paint
private Paint okPaint;
// 背景圆圈的半径
private int myRadius;
// 绘制打勾的路径
private Path path = new Path();
// 绘制路径的长度,也可以理解为完成度
private PathMeasure pathMeasure;
// 绘制对勾(√)的动画
private ValueAnimator animator_draw_ok;
// 对路径处理实现绘制动画效果
private PathEffect effect;
private boolean startDrawOk;
public OkView(Context context) {
this(context, null);
}
public OkView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public OkView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
paint = new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
okPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
okPaint.setStrokeWidth(5);
okPaint.setStyle(Paint.Style.STROKE);
okPaint.setStrokeCap(Paint.Cap.ROUND);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(getWidth() / 2, getHeight() / 2, myRadius, paint);
if (startDrawOk) {
canvas.drawPath(path, okPaint);
}
}
public void setOkColor(int color) {
okPaint.setColor(color);
}
public void setCircleColor(int color) {
paint.setColor(color);
}
public void setRadius(int radius) {
myRadius = radius;
// 对勾的路径
int cHeight = radius * 2;
path.moveTo(+cHeight / 8 * 3, cHeight / 2);
path.lineTo(+cHeight / 2, cHeight / 5 * 3);
path.lineTo(+cHeight / 3 * 2, cHeight / 5 * 2);
pathMeasure = new PathMeasure(path, true);
invalidate();
}
public void start(int duration) {
animator_draw_ok = ValueAnimator.ofFloat(1, 0);
animator_draw_ok.setDuration(duration);
animator_draw_ok.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
startDrawOk = true;
float value = (Float) animation.getAnimatedValue();
effect = new DashPathEffect(new float[] { pathMeasure.getLength(), pathMeasure.getLength() }, value * pathMeasure.getLength());
okPaint.setPathEffect(effect);
invalidate();
}
});
animator_draw_ok.start();
}
}
17
Source : TimeLineChartRenderer.java
with MIT License
from LambdaXiao
with MIT License
from LambdaXiao
public void drawCircleDashMarker(Canvas canvas, ILineDataSet dataSet, int count) {
// 画虚线圆点和MarkerView
PathEffect effects = new DashPathEffect(new float[] { 5, 5, 5, 5 }, 1);
Path path = new Path();
// 应为这里会复用之前的mLineBuffer,在总长度不变的情况下,取一般就是之前的位置,mXBounds.range + mXBounds.min 是最新的K线的变动范围
int pointOffset = (mXBounds.range + mXBounds.min + 1) * 4;
if (dataSet.getEntryCount() != 0) {
// 画虚线参数设置
path.moveTo(mLineBuffer[pointOffset - 2], mLineBuffer[pointOffset - 1]);
path.lineTo(mViewPortHandler.contentRight(), mLineBuffer[pointOffset - 1]);
mRenderPaint.setPathEffect(effects);
// Utils.convertDpToPixel(35)
Entry e = dataSet.getEntryForIndex(count - 1);
mRenderPaint.setTextSize(Utils.convertDpToPixel(10));
String text = NumberUtils.keepPrecisionR(e.getY(), dataSet.getPrecision());
int width = Utils.calcTextWidth(mRenderPaint, text);
int height = Utils.calcTextHeight(mRenderPaint, text);
float rectLeft = mViewPortHandler.contentRight() - width - Utils.convertDpToPixel(4);
float circleX = mLineBuffer[pointOffset - 2];
if (circleX >= rectLeft) {
mRenderPaint.setColor(Color.parseColor("#A65198FA"));
mRenderPaint.setStyle(Paint.Style.FILL);
float x = mLineBuffer[pointOffset - 2];
float y = mLineBuffer[pointOffset - 1];
if (y > mViewPortHandler.contentTop() + mViewPortHandler.getChartHeight() / 2) {
canvas.drawRect(rectLeft, y - Utils.convertDpToPixel(22), mViewPortHandler.contentRight(), y - Utils.convertDpToPixel(6), mRenderPaint);
Path pathS = new Path();
// 此点为多边形的起点
pathS.moveTo(x, y - Utils.convertDpToPixel(3));
pathS.lineTo(x - Utils.convertDpToPixel(3), y - Utils.convertDpToPixel(6));
pathS.lineTo(x + Utils.convertDpToPixel(3), y - Utils.convertDpToPixel(6));
// 使这些点构成封闭的多边形
pathS.close();
canvas.drawPath(pathS, mRenderPaint);
mRenderPaint.setColor(Color.parseColor("#66FFFFFF"));
canvas.drawText(text, rectLeft + Utils.convertDpToPixel(2), y - Utils.convertDpToPixel(10), mRenderPaint);
} else {
canvas.drawRect(rectLeft, y + Utils.convertDpToPixel(6), mViewPortHandler.contentRight(), y + Utils.convertDpToPixel(22), mRenderPaint);
Path pathS = new Path();
// 此点为多边形的起点
pathS.moveTo(x, y + Utils.convertDpToPixel(1));
pathS.lineTo(x - Utils.convertDpToPixel(3), y + Utils.convertDpToPixel(6));
pathS.lineTo(x + Utils.convertDpToPixel(3), y + Utils.convertDpToPixel(6));
// 使这些点构成封闭的多边形
pathS.close();
canvas.drawPath(pathS, mRenderPaint);
mRenderPaint.setColor(Color.parseColor("#66FFFFFF"));
canvas.drawText(text, rectLeft + Utils.convertDpToPixel(2), y + Utils.convertDpToPixel(10) + height, mRenderPaint);
}
} else {
canvas.drawPath(path, mRenderPaint);
mRenderPaint.setStyle(Paint.Style.FILL);
canvas.drawRect(rectLeft, mLineBuffer[pointOffset - 1] - Utils.convertDpToPixel(8), mViewPortHandler.contentRight(), mLineBuffer[pointOffset - 1] + Utils.convertDpToPixel(8), mRenderPaint);
mRenderPaint.setColor(Color.parseColor("#FFFFFF"));
canvas.drawText(text, rectLeft + Utils.convertDpToPixel(2), mLineBuffer[pointOffset - 1] + Utils.convertDpToPixel(3), mRenderPaint);
}
}
mRenderPaint.setColor(Color.RED);
postPosition(dataSet, mLineBuffer[pointOffset - 2], mLineBuffer[pointOffset - 1]);
}
17
Source : PathPaintView.java
with Apache License 2.0
from InnoFang
with Apache License 2.0
from InnoFang
/**
* Author: Inno Fang
* Time: 2017/1/12 21:40
* Description:
*/
public clreplaced PathPaintView extends View {
private static final String TAG = "PathTracingView";
private Path mPath;
private Paint mPaint;
private float mLength;
private float mAnimValue;
private PathMeasure mPathMeasure;
private PathEffect mPathEffect;
public PathPaintView(Context context) {
super(context);
}
public PathPaintView(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
mPath = new Path();
mPath.moveTo(100, 100);
mPath.lineTo(100, 500);
mPath.lineTo(400, 300);
mPath.close();
mPathMeasure = new PathMeasure();
mPathMeasure.setPath(mPath, true);
mLength = mPathMeasure.getLength();
ValueAnimator animator = ValueAnimator.ofFloat(1, 0);
animator.setDuration(2000);
animator.setInterpolator(new LinearInterpolator());
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mAnimValue = (float) animation.getAnimatedValue();
mPathEffect = new DashPathEffect(new float[] { mLength, mLength }, mLength * mAnimValue);
mPaint.setPathEffect(mPathEffect);
invalidate();
}
});
animator.start();
}
public PathPaintView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPath(mPath, mPaint);
}
}
17
Source : Line.java
with Apache License 2.0
from huashengzzz
with Apache License 2.0
from huashengzzz
/**
* Single line for line chart.
*/
public clreplaced Line {
private static final int DEFAULT_LINE_STROKE_WIDTH_DP = 3;
private static final int DEFAULT_POINT_RADIUS_DP = 6;
private static final int DEFAULT_AREA_TRANSPARENCY = 64;
public static final int UNINITIALIZED = 0;
private int color = ChartUtils.DEFAULT_COLOR;
private int pointColor = UNINITIALIZED;
private int darkenColor = ChartUtils.DEFAULT_DARKEN_COLOR;
/**
* Transparency of area when line is filled. *
*/
private int areaTransparency = DEFAULT_AREA_TRANSPARENCY;
private int strokeWidth = DEFAULT_LINE_STROKE_WIDTH_DP;
private int pointRadius = DEFAULT_POINT_RADIUS_DP;
private boolean hasGradientToTransparent = false;
private boolean hasPoints = true;
private boolean hasLines = true;
private boolean hasLabels = false;
private boolean hasLabelsOnlyForSelected = false;
private boolean isCubic = false;
private boolean isSquare = false;
private boolean isFilled = false;
private ValueShape shape = ValueShape.CIRCLE;
private PathEffect pathEffect;
private LineChartValueFormatter formatter = new SimpleLineChartValueFormatter();
private List<PointValue> values = new ArrayList<PointValue>();
public Line() {
}
public Line(List<PointValue> values) {
setValues(values);
}
public Line(Line line) {
this.color = line.color;
this.pointColor = line.pointColor;
this.darkenColor = line.darkenColor;
this.areaTransparency = line.areaTransparency;
this.strokeWidth = line.strokeWidth;
this.pointRadius = line.pointRadius;
this.hasGradientToTransparent = line.hasGradientToTransparent;
this.hasPoints = line.hasPoints;
this.hasLines = line.hasLines;
this.hasLabels = line.hasLabels;
this.hasLabelsOnlyForSelected = line.hasLabelsOnlyForSelected;
this.isSquare = line.isSquare;
this.isCubic = line.isCubic;
this.isFilled = line.isFilled;
this.shape = line.shape;
this.pathEffect = line.pathEffect;
this.formatter = line.formatter;
for (PointValue pointValue : line.values) {
this.values.add(new PointValue(pointValue));
}
}
public void update(float scale) {
for (PointValue value : values) {
value.update(scale);
}
}
public void finish() {
for (PointValue value : values) {
value.finish();
}
}
public List<PointValue> getValues() {
return this.values;
}
public void setValues(List<PointValue> values) {
if (null == values) {
this.values = new ArrayList<PointValue>();
} else {
this.values = values;
}
}
public int getColor() {
return color;
}
public Line setColor(int color) {
this.color = color;
if (pointColor == UNINITIALIZED) {
this.darkenColor = ChartUtils.darkenColor(color);
}
return this;
}
public int getPointColor() {
if (pointColor == UNINITIALIZED) {
return color;
} else {
return pointColor;
}
}
public Line setPointColor(int pointColor) {
this.pointColor = pointColor;
if (pointColor == UNINITIALIZED) {
this.darkenColor = ChartUtils.darkenColor(color);
} else {
this.darkenColor = ChartUtils.darkenColor(pointColor);
}
return this;
}
public int getDarkenColor() {
return darkenColor;
}
/**
* @see #setAreaTransparency(int)
*/
public int getAreaTransparency() {
return areaTransparency;
}
/**
* Set area transparency(255 is full opacity) for filled lines
*
* @param areaTransparency
* @return
*/
public Line setAreaTransparency(int areaTransparency) {
this.areaTransparency = areaTransparency;
return this;
}
public int getStrokeWidth() {
return strokeWidth;
}
public Line setStrokeWidth(int strokeWidth) {
this.strokeWidth = strokeWidth;
return this;
}
public boolean hasPoints() {
return hasPoints;
}
public Line setHasPoints(boolean hasPoints) {
this.hasPoints = hasPoints;
return this;
}
public boolean hasLines() {
return hasLines;
}
public Line setHasLines(boolean hasLines) {
this.hasLines = hasLines;
return this;
}
public boolean hasLabels() {
return hasLabels;
}
public Line setHasLabels(boolean hasLabels) {
this.hasLabels = hasLabels;
if (hasLabels) {
this.hasLabelsOnlyForSelected = false;
}
return this;
}
/**
* @see #setHasLabelsOnlyForSelected(boolean)
*/
public boolean hasLabelsOnlyForSelected() {
return hasLabelsOnlyForSelected;
}
/**
* Set true if you want to show value labels only for selected value, works best when chart has
* isValueSelectionEnabled set to true {@link Chart#setValueSelectionEnabled(boolean)}.
*/
public Line setHasLabelsOnlyForSelected(boolean hasLabelsOnlyForSelected) {
this.hasLabelsOnlyForSelected = hasLabelsOnlyForSelected;
if (hasLabelsOnlyForSelected) {
this.hasLabels = false;
}
return this;
}
public int getPointRadius() {
return pointRadius;
}
/**
* Set radius for points for this line.
*
* @param pointRadius
* @return
*/
public Line setPointRadius(int pointRadius) {
this.pointRadius = pointRadius;
return this;
}
public boolean getGradientToTransparent() {
return hasGradientToTransparent;
}
public Line setHasGradientToTransparent(boolean hasGradientToTransparent) {
this.hasGradientToTransparent = hasGradientToTransparent;
return this;
}
public boolean isCubic() {
return isCubic;
}
public Line setCubic(boolean isCubic) {
this.isCubic = isCubic;
if (isSquare)
setSquare(false);
return this;
}
public boolean isSquare() {
return isSquare;
}
public Line setSquare(boolean isSquare) {
this.isSquare = isSquare;
if (isCubic)
setCubic(false);
return this;
}
public boolean isFilled() {
return isFilled;
}
public Line setFilled(boolean isFilled) {
this.isFilled = isFilled;
return this;
}
/**
* @see #setShape(ValueShape)
*/
public ValueShape getShape() {
return shape;
}
/**
* Set shape for points, possible values: SQUARE, CIRCLE
*
* @param shape
* @return
*/
public Line setShape(ValueShape shape) {
this.shape = shape;
return this;
}
public PathEffect getPathEffect() {
return pathEffect;
}
/**
* Set path effect for this line, note: it will slow down drawing, try to not use complicated effects,
* DashPathEffect should be safe choice.
*
* @param pathEffect
*/
public void setPathEffect(PathEffect pathEffect) {
this.pathEffect = pathEffect;
}
public LineChartValueFormatter getFormatter() {
return formatter;
}
public Line setFormatter(LineChartValueFormatter formatter) {
if (null != formatter) {
this.formatter = formatter;
}
return this;
}
}
17
Source : Line.java
with Apache License 2.0
from hanFengSan
with Apache License 2.0
from hanFengSan
/**
* Single line for line chart.
*/
public clreplaced Line {
private static final int DEFAULT_LINE_STROKE_WIDTH_DP = 3;
private static final int DEFAULT_POINT_RADIUS_DP = 6;
private static final int DEFAULT_AREA_TRANSPARENCY = 64;
public static final int UNINITIALIZED = 0;
private int color = ChartUtils.DEFAULT_COLOR;
private int pointColor = UNINITIALIZED;
private int darkenColor = ChartUtils.DEFAULT_DARKEN_COLOR;
/**
* Transparency of area when line is filled. *
*/
private int areaTransparency = DEFAULT_AREA_TRANSPARENCY;
private int strokeWidth = DEFAULT_LINE_STROKE_WIDTH_DP;
private int pointRadius = DEFAULT_POINT_RADIUS_DP;
private boolean hasPoints = true;
private boolean hasLines = true;
private boolean hasLabels = false;
private boolean hasLabelsOnlyForSelected = false;
private boolean isCubic = false;
private boolean isSquare = false;
private boolean isFilled = false;
private ValueShape shape = ValueShape.CIRCLE;
private PathEffect pathEffect;
private LineChartValueFormatter formatter = new SimpleLineChartValueFormatter();
private List<PointValue> values = new ArrayList<PointValue>();
public Line() {
}
public Line(List<PointValue> values) {
setValues(values);
}
public Line(Line line) {
this.color = line.color;
this.pointColor = line.pointColor;
this.darkenColor = line.darkenColor;
this.areaTransparency = line.areaTransparency;
this.strokeWidth = line.strokeWidth;
this.pointRadius = line.pointRadius;
this.hasPoints = line.hasPoints;
this.hasLines = line.hasLines;
this.hasLabels = line.hasLabels;
this.hasLabelsOnlyForSelected = line.hasLabelsOnlyForSelected;
this.isSquare = line.isSquare;
this.isCubic = line.isCubic;
this.isFilled = line.isFilled;
this.shape = line.shape;
this.pathEffect = line.pathEffect;
this.formatter = line.formatter;
for (PointValue pointValue : line.values) {
this.values.add(new PointValue(pointValue));
}
}
public void update(float scale) {
for (PointValue value : values) {
value.update(scale);
}
}
public void finish() {
for (PointValue value : values) {
value.finish();
}
}
public List<PointValue> getValues() {
return this.values;
}
public void setValues(List<PointValue> values) {
if (null == values) {
this.values = new ArrayList<PointValue>();
} else {
this.values = values;
}
}
public int getColor() {
return color;
}
public Line setColor(int color) {
this.color = color;
if (pointColor == UNINITIALIZED) {
this.darkenColor = ChartUtils.darkenColor(color);
}
return this;
}
public int getPointColor() {
if (pointColor == UNINITIALIZED) {
return color;
} else {
return pointColor;
}
}
public Line setPointColor(int pointColor) {
this.pointColor = pointColor;
if (pointColor == UNINITIALIZED) {
this.darkenColor = ChartUtils.darkenColor(color);
} else {
this.darkenColor = ChartUtils.darkenColor(pointColor);
}
return this;
}
public int getDarkenColor() {
return darkenColor;
}
/**
* @see #setAreaTransparency(int)
*/
public int getAreaTransparency() {
return areaTransparency;
}
/**
* Set area transparency(255 is full opacity) for filled lines
*
* @param areaTransparency
* @return
*/
public Line setAreaTransparency(int areaTransparency) {
this.areaTransparency = areaTransparency;
return this;
}
public int getStrokeWidth() {
return strokeWidth;
}
public Line setStrokeWidth(int strokeWidth) {
this.strokeWidth = strokeWidth;
return this;
}
public boolean hasPoints() {
return hasPoints;
}
public Line setHasPoints(boolean hasPoints) {
this.hasPoints = hasPoints;
return this;
}
public boolean hasLines() {
return hasLines;
}
public Line setHasLines(boolean hasLines) {
this.hasLines = hasLines;
return this;
}
public boolean hasLabels() {
return hasLabels;
}
public Line setHasLabels(boolean hasLabels) {
this.hasLabels = hasLabels;
if (hasLabels) {
this.hasLabelsOnlyForSelected = false;
}
return this;
}
/**
* @see #setHasLabelsOnlyForSelected(boolean)
*/
public boolean hasLabelsOnlyForSelected() {
return hasLabelsOnlyForSelected;
}
/**
* Set true if you want to show value labels only for selected value, works best when chart has
* isValueSelectionEnabled set to true {@link Chart#setValueSelectionEnabled(boolean)}.
*/
public Line setHasLabelsOnlyForSelected(boolean hasLabelsOnlyForSelected) {
this.hasLabelsOnlyForSelected = hasLabelsOnlyForSelected;
if (hasLabelsOnlyForSelected) {
this.hasLabels = false;
}
return this;
}
public int getPointRadius() {
return pointRadius;
}
/**
* Set radius for points for this line.
*
* @param pointRadius
* @return
*/
public Line setPointRadius(int pointRadius) {
this.pointRadius = pointRadius;
return this;
}
public boolean isCubic() {
return isCubic;
}
public Line setCubic(boolean isCubic) {
this.isCubic = isCubic;
if (isSquare)
setSquare(false);
return this;
}
public boolean isSquare() {
return isSquare;
}
public Line setSquare(boolean isSquare) {
this.isSquare = isSquare;
if (isCubic)
setCubic(false);
return this;
}
public boolean isFilled() {
return isFilled;
}
public Line setFilled(boolean isFilled) {
this.isFilled = isFilled;
return this;
}
/**
* @see #setShape(ValueShape)
*/
public ValueShape getShape() {
return shape;
}
/**
* Set shape for points, possible values: SQUARE, CIRCLE
*
* @param shape
* @return
*/
public Line setShape(ValueShape shape) {
this.shape = shape;
return this;
}
public PathEffect getPathEffect() {
return pathEffect;
}
/**
* Set path effect for this line, note: it will slow down drawing, try to not use complicated effects,
* DashPathEffect should be safe choice.
*
* @param pathEffect
*/
public void setPathEffect(PathEffect pathEffect) {
this.pathEffect = pathEffect;
}
public LineChartValueFormatter getFormatter() {
return formatter;
}
public Line setFormatter(LineChartValueFormatter formatter) {
if (null != formatter) {
this.formatter = formatter;
}
return this;
}
}
17
Source : ChatHeadOverlayView.java
with BSD 2-Clause "Simplified" License
from Denny966
with BSD 2-Clause "Simplified" License
from Denny966
public clreplaced ChatHeadOverlayView extends View {
private static final long ANIMATION_DURATION = 600;
private float OVAL_RADIUS;
private float STAMP_SPACING;
private Path arrowDashedPath;
private Paint paint = new Paint();
private ObjectAnimator animator;
private PathEffect pathDashEffect;
public ChatHeadOverlayView(Context context) {
super(context);
init(context);
}
public ChatHeadOverlayView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
STAMP_SPACING = ChatHeadUtils.dpToPx(context, 20);
OVAL_RADIUS = ChatHeadUtils.dpToPx(context, 3);
animator = ObjectAnimator.ofFloat(this, "phase", 0f, -STAMP_SPACING);
animator.setInterpolator(new LinearInterpolator());
animator.setRepeatMode(ValueAnimator.RESTART);
animator.setRepeatCount(ValueAnimator.INFINITE);
animator.setDuration(ANIMATION_DURATION);
}
public ChatHeadOverlayView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (arrowDashedPath != null) {
paint.setPathEffect(pathDashEffect);
canvas.drawPath(arrowDashedPath, paint);
}
}
/**
* taken from https://github.com/romainguy/road-trip/blob/master/application/src/main/java/org/curiouscreature/android/roadtrip/IntroView.java *
*/
private Path makeDot(float radius) {
Path p = new Path();
p.addCircle(0, 0, radius, Path.Direction.CCW);
return p;
}
public void drawPath(float fromX, float fromY, float toX, float toY) {
arrowDashedPath = new Path();
arrowDashedPath.moveTo(fromX, fromY);
arrowDashedPath.lineTo(toX, toY);
paint.setColor(Color.parseColor("#77FFFFFF"));
// width = diameter
paint.setStrokeWidth(OVAL_RADIUS * 2);
animatePath();
invalidate();
}
/**
* Will be called by animator
* @param phase
*/
private void setPhase(float phase) {
pathDashEffect = new PathDashPathEffect(makeDot(OVAL_RADIUS), STAMP_SPACING, phase, PathDashPathEffect.Style.ROTATE);
invalidate();
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void animatePath() {
animator.start();
}
public void clearPath() {
animator.cancel();
arrowDashedPath = null;
invalidate();
}
}
17
Source : RecyclerViewItemDecoration.java
with Apache License 2.0
from arjinmc
with Apache License 2.0
from arjinmc
/**
* draw horizonal decoration
*
* @param c
* @param parent
*/
private void drawHorinzonal(Canvas c, RecyclerView parent) {
int childrentCount = parent.getChildCount();
if (drawableRid != 0) {
if (hasNinePatch) {
for (int i = 0; i < childrentCount; i++) {
if (i != childrentCount - 1) {
View childView = parent.getChildAt(i);
int myY = childView.getBottom();
Rect rect = new Rect(0, myY, parent.getWidth(), myY + bmp.getHeight());
ninePatch.draw(c, rect);
}
}
} else {
for (int i = 0; i < childrentCount; i++) {
if (i != childrentCount - 1) {
View childView = parent.getChildAt(i);
int myY = childView.getBottom();
c.drawBitmap(bmp, 0, myY, paint);
}
}
}
} else if (dashWidth == 0 && dashGap == 0) {
for (int i = 0; i < childrentCount; i++) {
if (i != childrentCount - 1) {
View childView = parent.getChildAt(i);
int myY = childView.getBottom() + thick / 2;
c.drawLine(0, myY, parent.getWidth(), myY, paint);
}
}
} else {
PathEffect effects = new DashPathEffect(new float[] { 0, 0, dashWidth, thick }, dashGap);
paint.setPathEffect(effects);
for (int i = 0; i < childrentCount; i++) {
if (i != childrentCount - 1) {
View childView = parent.getChildAt(i);
int myY = childView.getBottom() + thick / 2;
Path path = new Path();
path.moveTo(0, myY);
path.lineTo(parent.getWidth(), myY);
c.drawPath(path, paint);
}
}
}
}
17
Source : RecyclerViewItemDecoration.java
with Apache License 2.0
from arjinmc
with Apache License 2.0
from arjinmc
/**
* 画网格分割线
*
* @param c
* @param parent
*/
private void drawGrid(Canvas c, RecyclerView parent) {
int childrentCount = parent.getChildCount();
int columnSize = ((GridLayoutManager) parent.getLayoutManager()).getSpanCount();
int adapterChildrenCount = parent.getAdapter().gereplacedemCount();
if (drawableRid != 0) {
if (hasNinePatch) {
for (int i = 0; i < childrentCount; i++) {
View childView = parent.getChildAt(i);
int myX = childView.getRight();
int myY = childView.getBottom();
// horizonal
if (!isLastRowGrid(i, adapterChildrenCount, columnSize)) {
Rect rect = new Rect(0, myY, myX, myY + bmp.getHeight());
ninePatch.draw(c, rect);
}
// vertical
if (isLastRowGrid(i, adapterChildrenCount, columnSize) && !isLastGridColumn(i, columnSize)) {
Rect rect = new Rect(myX, childView.getTop(), myX + bmp.getWidth(), myY);
ninePatch.draw(c, rect);
} else if (!isLastGridColumn(i, columnSize)) {
Rect rect = new Rect(myX, childView.getTop(), myX + bmp.getWidth(), myY + bmp.getHeight());
ninePatch.draw(c, rect);
}
}
} else {
for (int i = 0; i < childrentCount; i++) {
View childView = parent.getChildAt(i);
int myX = childView.getRight();
int myY = childView.getBottom();
// horizonal
if (!isLastRowGrid(i, adapterChildrenCount, columnSize)) {
c.drawBitmap(bmp, childView.getLeft(), myY, paint);
}
// vertical
if (!isLastGridColumn(i, columnSize)) {
c.drawBitmap(bmp, myX, childView.getTop(), paint);
}
}
}
} else if (dashWidth == 0 && dashGap == 0) {
for (int i = 0; i < childrentCount; i++) {
View childView = parent.getChildAt(i);
int myX = childView.getRight() + thick / 2;
int myY = childView.getBottom() + thick / 2;
// horizonal
if (!isLastRowGrid(i, adapterChildrenCount, columnSize)) {
c.drawLine(childView.getLeft(), myY, childView.getRight() + thick, myY, paint);
}
// vertical
if (isLastRowGrid(i, adapterChildrenCount, columnSize) && !isLastGridColumn(i, columnSize)) {
c.drawLine(myX, childView.getTop(), myX, childView.getBottom(), paint);
} else if (!isLastGridColumn(i, columnSize)) {
c.drawLine(myX, childView.getTop(), myX, myY, paint);
}
}
} else {
PathEffect effects = new DashPathEffect(new float[] { 0, 0, dashWidth, thick }, dashGap);
paint.setPathEffect(effects);
for (int i = 0; i < childrentCount; i++) {
View childView = parent.getChildAt(i);
int myX = childView.getRight() + thick / 2;
int myY = childView.getBottom() + thick / 2;
// horizonal
if (!isLastRowGrid(i, adapterChildrenCount, columnSize)) {
Path path = new Path();
path.moveTo(0, myY);
path.lineTo(myX, myY);
c.drawPath(path, paint);
}
// vertical
if (isLastRowGrid(i, adapterChildrenCount, columnSize) && !isLastGridColumn(i, columnSize)) {
Path path = new Path();
path.moveTo(myX, childView.getTop());
path.lineTo(myX, childView.getBottom());
c.drawPath(path, paint);
} else if (!isLastGridColumn(i, columnSize)) {
Path path = new Path();
path.moveTo(myX, childView.getTop());
path.lineTo(myX, childView.getBottom());
c.drawPath(path, paint);
}
}
}
}
17
Source : RecyclerViewItemDecoration.java
with Apache License 2.0
from arjinmc
with Apache License 2.0
from arjinmc
/**
* draw vertival decoration
*
* @param c
* @param parent
*/
private void drawVertical(Canvas c, RecyclerView parent) {
int childrentCount = parent.getChildCount();
if (drawableRid != 0) {
if (hasNinePatch) {
for (int i = 0; i < childrentCount; i++) {
if (i != childrentCount - 1) {
View childView = parent.getChildAt(i);
int myX = childView.getRight();
Rect rect = new Rect(myX, 0, myX + bmp.getWidth(), parent.getHeight());
ninePatch.draw(c, rect);
}
}
} else {
for (int i = 0; i < childrentCount; i++) {
if (i != childrentCount - 1) {
View childView = parent.getChildAt(i);
int myX = childView.getRight();
c.drawBitmap(bmp, myX, 0, paint);
}
}
}
} else if (dashWidth == 0 && dashGap == 0) {
for (int i = 0; i < childrentCount; i++) {
if (i != childrentCount - 1) {
View childView = parent.getChildAt(i);
int myX = childView.getRight() + thick / 2;
c.drawLine(myX, 0, myX, parent.getHeight(), paint);
}
}
} else {
PathEffect effects = new DashPathEffect(new float[] { 0, 0, dashWidth, thick }, dashGap);
paint.setPathEffect(effects);
for (int i = 0; i < childrentCount; i++) {
if (i != childrentCount - 1) {
View childView = parent.getChildAt(i);
int myX = childView.getRight() + thick / 2;
Path path = new Path();
path.moveTo(myX, 0);
path.lineTo(myX, parent.getHeight());
c.drawPath(path, paint);
}
}
}
}
17
Source : VirtualLine.java
with MIT License
from alibaba
with MIT License
from alibaba
@Override
public void onParseValueFinished() {
super.onParseValueFinished();
mPaint.setStrokeWidth(mLineWidth);
mPaint.setColor(mLineColor);
switch(mStyle) {
case LineBaseCommon.STYLE_DASH:
if (mPath == null) {
mPath = new Path();
}
mPath.reset();
mPaint.setStyle(Paint.Style.STROKE);
PathEffect effects = new DashPathEffect(mDashEffect, 1);
mPaint.setPathEffect(effects);
break;
case LineBaseCommon.STYLE_SOLID:
mPaint.setStyle(Paint.Style.FILL);
break;
default:
break;
}
}
16
Source : aaLinesChart.java
with Apache License 2.0
from openXu
with Apache License 2.0
from openXu
/**
* 绘制X轴方向辅助网格
*/
private void drawGrid(Canvas canvas) {
float yMarkSpace = (rectChart.bottom - rectChart.top) / (YMARK_NUM - 1);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(lineWidth);
paint.setColor(defColor);
paintEffect.setStyle(Paint.Style.STROKE);
paintEffect.setStrokeWidth(lineWidth);
paintEffect.setColor(defColor);
canvas.drawLine(rectChart.left, rectChart.top, rectChart.left, rectChart.bottom, paint);
canvas.drawLine(rectChart.right, rectChart.top, rectChart.right, rectChart.bottom, paint);
for (int i = 0; i < YMARK_NUM; i++) {
if (i == 0 || i == YMARK_NUM - 1) {
// 实线
canvas.drawLine(rectChart.left, rectChart.bottom - yMarkSpace * i, rectChart.right, rectChart.bottom - yMarkSpace * i, paint);
} else {
// 虚线
Path path = new Path();
path.moveTo(rectChart.left, rectChart.bottom - yMarkSpace * i);
path.lineTo(rectChart.right, rectChart.bottom - yMarkSpace * i);
PathEffect effects = new DashPathEffect(new float[] { 15, 8, 15, 8 }, 0);
paintEffect.setPathEffect(effects);
canvas.drawPath(path, paintEffect);
}
}
}
16
Source : NorthSouthChart.java
with Apache License 2.0
from openXu
with Apache License 2.0
from openXu
/**
* 绘制X轴方向辅助网格
*/
private void drawGrid(Canvas canvas) {
float yMarkSpace = (rectChart.bottom - rectChart.top) / (YMARK_NUM - 1);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(lineWidth);
paint.setColor(defColor);
paintEffect.setStyle(Paint.Style.STROKE);
paintEffect.setStrokeWidth(lineWidth);
paintEffect.setColor(defColor);
canvas.drawLine(rectChart.left, rectChart.top, rectChart.left, rectChart.bottom, paint);
canvas.drawLine(rectChart.right, rectChart.top, rectChart.right, rectChart.bottom, paint);
if (chartType == ChartType.TYPE_T_SOUTH || chartType == ChartType.TYPE_T_NORTH) {
// 今日图表,需要绘制x刻度线
for (DataPoint lable : lableXPointList) {
canvas.drawLine(lable.getValueY(), rectChart.bottom, lable.getValueY(), rectChart.bottom - DensityUtil.dip2px(getContext(), 3), paint);
}
}
for (int i = 0; i < YMARK_NUM; i++) {
if (i == 0 || i == YMARK_NUM - 1) {
// 实线
canvas.drawLine(rectChart.left, rectChart.bottom - yMarkSpace * i, rectChart.right, rectChart.bottom - yMarkSpace * i, paint);
} else {
// 虚线
Path path = new Path();
path.moveTo(rectChart.left, rectChart.bottom - yMarkSpace * i);
path.lineTo(rectChart.right, rectChart.bottom - yMarkSpace * i);
PathEffect effects = new DashPathEffect(new float[] { 15, 8, 15, 8 }, 0);
paintEffect.setPathEffect(effects);
canvas.drawPath(path, paintEffect);
}
}
}
16
Source : WeekWeatherView.java
with MIT License
from byhieg
with MIT License
from byhieg
private void init(Context context) {
baseLinePaint = new Paint();
baseLinePaint.setColor(ContextCompat.getColor(context, R.color.maincolor));
baseLinePaint.setAntiAlias(true);
baseLinePaint.setStyle(Paint.Style.FILL);
baseLinePaint.setStrokeWidth(10);
verticalLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
verticalLinePaint.setStyle(Paint.Style.STROKE);
verticalLinePaint.setColor(ContextCompat.getColor(context, R.color.lightgray));
verticalLinePaint.setAntiAlias(true);
verticalLinePaint.setStrokeWidth(5);
verticalLinePaint.setStrokeCap(Paint.Cap.ROUND);
PathEffect effect = new DashPathEffect(new float[] { 1, 2, 4, 8 }, 1);
verticalLinePaint.setPathEffect(effect);
verticalLinePaint.setStrokeJoin(Paint.Join.ROUND);
highPointPaint = new Paint();
highPointPaint.setColor(ContextCompat.getColor(context, R.color.red));
highPointPaint.setAntiAlias(true);
highPointPaint.setStyle(Paint.Style.STROKE);
highPointPaint.setStrokeWidth(5);
lowPointPaint = new Paint();
lowPointPaint.setColor(ContextCompat.getColor(context, R.color.maincolor));
lowPointPaint.setAntiAlias(true);
lowPointPaint.setStyle(Paint.Style.STROKE);
lowPointPaint.setStrokeWidth(5);
highLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
highLinePaint.setColor(ContextCompat.getColor(context, R.color.red));
highLinePaint.setAntiAlias(true);
highLinePaint.setStrokeWidth(5);
highLinePaint.setStrokeCap(Paint.Cap.ROUND);
highLinePaint.setStrokeJoin(Paint.Join.ROUND);
highLinePaint.setStyle(Paint.Style.STROKE);
lowLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
lowLinePaint.setColor(ContextCompat.getColor(context, R.color.cadetblue));
lowLinePaint.setAntiAlias(true);
lowLinePaint.setStrokeWidth(5);
lowLinePaint.setStrokeCap(Paint.Cap.ROUND);
lowLinePaint.setStrokeJoin(Paint.Join.ROUND);
lowLinePaint.setStyle(Paint.Style.STROKE);
mPath = new Path();
dPath = new Path();
textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(ContextCompat.getColor(context, R.color.black));
String familyName = "宋体";
Typeface font = Typeface.create(familyName, Typeface.BOLD);
textPaint.setTypeface(font);
textPaint.setTextAlign(Paint.Align.CENTER);
lowTempPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
lowTempPaint.setColor(ContextCompat.getColor(context, R.color.cadetblue));
lowTempPaint.setTypeface(font);
lowTempPaint.setTextAlign(Paint.Align.CENTER);
highTempPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
highTempPaint.setColor(ContextCompat.getColor(context, R.color.red));
highTempPaint.setTypeface(font);
highTempPaint.setTextAlign(Paint.Align.CENTER);
}
15
Source : SunriseSunsetView.java
with Apache License 2.0
from tianma8023
with Apache License 2.0
from tianma8023
/**
* A view which can show sunrise and sunset animation
*/
public clreplaced SunriseSunsetView extends View {
private static final int DEFAULT_TRACK_COLOR = Color.WHITE;
private static final int DEFAULT_TRACK_WIDTH_PX = 4;
private static final int DEFAULT_SUN_COLOR = Color.YELLOW;
private static final int DEFAULT_SUN_RADIUS_PX = 20;
private static final int DEFAULT_SUN_STROKE_WIDTH_PX = 4;
private static final int DEFAULT_SHADOW_COLOR = Color.parseColor("#32FFFFFF");
private static final int DEFAULT_LABEL_TEXT_COLOR = Color.WHITE;
private static final int DEFAULT_LABEL_TEXT_SIZE = 40;
private static final int DEFAULT_LABEL_VERTICAL_OFFSET_PX = 5;
private static final int DEFAULT_LABEL_HORIZONTAL_OFFSET_PX = 20;
/**
* 当前日出日落比率, mRatio < 0: 未日出, mRatio > 1 已日落
*/
private float mRatio;
// 绘制半圆轨迹的Paint
private Paint mTrackPaint;
// 轨迹的颜色
private int mTrackColor = DEFAULT_TRACK_COLOR;
// 轨迹的宽度
private int mTrackWidth = DEFAULT_TRACK_WIDTH_PX;
// 轨迹的PathEffect
private PathEffect mTrackPathEffect = new DashPathEffect(new float[] { 15, 15 }, 1);
// 轨迹圆的半径
private float mTrackRadius;
// 绘制日出日落阴影的Paint
private Paint mShadowPaint;
// 阴影颜色
private int mShadowColor = DEFAULT_SHADOW_COLOR;
// 绘制太阳的Paint
private Paint mSunPaint;
// 太阳颜色
private int mSunColor = DEFAULT_SUN_COLOR;
// 太阳半径
private float mSunRadius = DEFAULT_SUN_RADIUS_PX;
// 太阳Paint样式,默认FILL
private Paint.Style mSunPaintStyle = Paint.Style.FILL;
// 绘制日出日落时间的Paint
private TextPaint mLabelPaint;
// 标签文字大小
private int mLabelTextSize = DEFAULT_LABEL_TEXT_SIZE;
// 标签颜色
private int mLabelTextColor = DEFAULT_LABEL_TEXT_COLOR;
// 竖直方向间距
private int mLabelVerticalOffset = DEFAULT_LABEL_VERTICAL_OFFSET_PX;
// 水平方向间距
private int mLabelHorizontalOffset = DEFAULT_LABEL_HORIZONTAL_OFFSET_PX;
// 半圆轨迹最小半径
private static final int MINIMAL_TRACK_RADIUS_PX = 300;
/**
* 日出时间
*/
private Time mSunriseTime;
/**
* 日落时间
*/
private Time mSunsetTime;
/**
* 绘图区域
*/
private RectF mBoardRectF = new RectF();
// Label Formatter - Default is a Simple label formatter.
private SunriseSunsetLabelFormatter mLabelFormatter = new SimpleSunriseSunsetLabelFormatter();
public SunriseSunsetView(Context context) {
super(context);
init();
}
public SunriseSunsetView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SunriseSunsetView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SunriseSunsetView, defStyleAttr, 0);
if (a != null) {
mTrackColor = a.getColor(R.styleable.SunriseSunsetView_ssv_track_color, DEFAULT_TRACK_COLOR);
mTrackWidth = a.getDimensionPixelSize(R.styleable.SunriseSunsetView_ssv_track_width, DEFAULT_TRACK_WIDTH_PX);
mShadowColor = a.getColor(R.styleable.SunriseSunsetView_ssv_shadow_color, DEFAULT_SHADOW_COLOR);
mSunColor = a.getColor(R.styleable.SunriseSunsetView_ssv_sun_color, DEFAULT_SUN_COLOR);
mSunRadius = a.getDimensionPixelSize(R.styleable.SunriseSunsetView_ssv_sun_radius, DEFAULT_SUN_RADIUS_PX);
mLabelTextColor = a.getColor(R.styleable.SunriseSunsetView_ssv_label_text_color, DEFAULT_LABEL_TEXT_COLOR);
mLabelTextSize = a.getDimensionPixelSize(R.styleable.SunriseSunsetView_ssv_label_text_size, DEFAULT_LABEL_TEXT_SIZE);
mLabelVerticalOffset = a.getDimensionPixelOffset(R.styleable.SunriseSunsetView_ssv_label_vertical_offset, DEFAULT_LABEL_VERTICAL_OFFSET_PX);
mLabelHorizontalOffset = a.getDimensionPixelOffset(R.styleable.SunriseSunsetView_ssv_label_horizontal_offset, DEFAULT_LABEL_HORIZONTAL_OFFSET_PX);
a.recycle();
}
init();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int paddingRight = getPaddingRight();
int paddingLeft = getPaddingLeft();
int paddingTop = getPaddingTop();
int paddingBottom = getPaddingBottom();
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
// 处理wrap_content这种情况
if (widthSpecMode == MeasureSpec.AT_MOST) {
widthSpecSize = paddingLeft + paddingRight + MINIMAL_TRACK_RADIUS_PX * 2 + (int) mSunRadius * 2;
}
mTrackRadius = 1.0f * (widthSpecSize - paddingLeft - paddingRight - 2 * mSunRadius) / 2;
int expectedHeight = (int) (mTrackRadius + mSunRadius + paddingBottom + paddingTop);
mBoardRectF.set(paddingLeft + mSunRadius, paddingTop + mSunRadius, widthSpecSize - paddingRight - mSunRadius, expectedHeight - paddingBottom);
setMeasuredDimension(widthSpecSize, expectedHeight);
}
private void init() {
// 初始化半圆轨迹的画笔
mTrackPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
// 画笔的样式为线条
mTrackPaint.setStyle(Paint.Style.STROKE);
prepareTrackPaint();
// 初始化日出日落阴影的画笔
mShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mShadowPaint.setStyle(Paint.Style.FILL_AND_STROKE);
prepareShadowPaint();
// 初始化太阳的Paint
mSunPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mSunPaint.setStrokeWidth(DEFAULT_SUN_STROKE_WIDTH_PX);
prepareSunPaint();
mLabelPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
prepareLabelPaint();
}
// 半圆轨迹的画笔
private void prepareTrackPaint() {
mTrackPaint.setColor(mTrackColor);
mTrackPaint.setStrokeWidth(mTrackWidth);
mTrackPaint.setPathEffect(mTrackPathEffect);
}
// 阴影的画笔
private void prepareShadowPaint() {
mShadowPaint.setColor(mShadowColor);
}
// 太阳的画笔
private void prepareSunPaint() {
mSunPaint.setColor(mSunColor);
mSunPaint.setStrokeWidth(DEFAULT_SUN_STROKE_WIDTH_PX);
mSunPaint.setStyle(mSunPaintStyle);
}
// 标签的画笔
private void prepareLabelPaint() {
mLabelPaint.setColor(mLabelTextColor);
mLabelPaint.setTextSize(mLabelTextSize);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawSunTrack(canvas);
drawShadow(canvas);
drawSun(canvas);
drawSunriseSunsetLabel(canvas);
}
// 绘制太阳轨道(半圆)
private void drawSunTrack(Canvas canvas) {
prepareTrackPaint();
canvas.save();
RectF rectF = new RectF(mBoardRectF.left, mBoardRectF.top, mBoardRectF.right, mBoardRectF.bottom + mBoardRectF.height());
canvas.drawArc(rectF, 180, 180, false, mTrackPaint);
canvas.restore();
}
// 绘制日出日落阴影部分
private void drawShadow(Canvas canvas) {
prepareShadowPaint();
canvas.save();
Path path = new Path();
float endY = mBoardRectF.bottom;
RectF rectF = new RectF(mBoardRectF.left, mBoardRectF.top, mBoardRectF.right, mBoardRectF.bottom + mBoardRectF.height());
float curPointX = mBoardRectF.left + mTrackRadius - mTrackRadius * (float) Math.cos(Math.PI * mRatio);
path.moveTo(0, endY);
path.arcTo(rectF, 180, 180 * mRatio);
path.lineTo(curPointX, endY);
path.close();
canvas.drawPath(path, mShadowPaint);
canvas.restore();
}
// 绘制太阳
private void drawSun(Canvas canvas) {
prepareSunPaint();
canvas.save();
float curPointX = mBoardRectF.left + mTrackRadius - mTrackRadius * (float) Math.cos(Math.PI * mRatio);
float curPointY = mBoardRectF.bottom - mTrackRadius * (float) Math.sin(Math.PI * mRatio);
canvas.drawCircle(curPointX, curPointY, mSunRadius, mSunPaint);
canvas.restore();
}
// 绘制日出日落标签
private void drawSunriseSunsetLabel(Canvas canvas) {
if (mSunriseTime == null || mSunsetTime == null) {
return;
}
prepareLabelPaint();
canvas.save();
// 绘制日出时间
String sunriseStr = mLabelFormatter.formatSunriseLabel(mSunriseTime);
mLabelPaint.setTextAlign(Paint.Align.LEFT);
Paint.FontMetricsInt metricsInt = mLabelPaint.getFontMetricsInt();
float baseLineX = mBoardRectF.left + mSunRadius + mLabelHorizontalOffset;
float baseLineY = mBoardRectF.bottom - metricsInt.bottom - mLabelVerticalOffset;
canvas.drawText(sunriseStr, baseLineX, baseLineY, mLabelPaint);
// 绘制日落时间
mLabelPaint.setTextAlign(Paint.Align.RIGHT);
String sunsetStr = mLabelFormatter.formatSunsetLabel(mSunsetTime);
baseLineX = mBoardRectF.right - mSunRadius - mLabelHorizontalOffset;
canvas.drawText(sunsetStr, baseLineX, baseLineY, mLabelPaint);
canvas.restore();
}
public void setRatio(float ratio) {
mRatio = ratio;
invalidate();
}
public void setSunriseTime(Time sunriseTime) {
mSunriseTime = sunriseTime;
}
public Time getSunriseTime() {
return mSunriseTime;
}
public void setSunsetTime(Time sunsetTime) {
mSunsetTime = sunsetTime;
}
public Time getSunsetTime() {
return mSunsetTime;
}
public float getSunRadius() {
return mSunRadius;
}
public SunriseSunsetLabelFormatter getLabelFormatter() {
return mLabelFormatter;
}
public void setLabelFormatter(SunriseSunsetLabelFormatter labelFormatter) {
mLabelFormatter = labelFormatter;
}
public void setTrackColor(int trackColor) {
mTrackColor = trackColor;
}
public void setTrackWidth(int trackWidthInPx) {
mTrackWidth = trackWidthInPx;
}
public void setTrackPathEffect(PathEffect trackPathEffect) {
mTrackPathEffect = trackPathEffect;
}
public void setSunColor(int sunColor) {
mSunColor = sunColor;
}
public void setSunRadius(float sunRadius) {
mSunRadius = sunRadius;
}
public void setSunPaintStyle(Paint.Style sunPaintStyle) {
mSunPaintStyle = sunPaintStyle;
}
public void setShadowColor(int shadowColor) {
mShadowColor = shadowColor;
}
public void setLabelTextSize(int labelTextSize) {
mLabelTextSize = labelTextSize;
}
public void setLabelTextColor(int labelTextColor) {
mLabelTextColor = labelTextColor;
}
public void setLabelVerticalOffset(int labelVerticalOffset) {
mLabelVerticalOffset = labelVerticalOffset;
}
public void setLabelHorizontalOffset(int labelHorizontalOffset) {
mLabelHorizontalOffset = labelHorizontalOffset;
}
public void startAnimate() {
if (mSunriseTime == null || mSunsetTime == null) {
throw new RuntimeException("You need to set both sunrise and sunset time before start animation");
}
int sunrise = mSunriseTime.transformToMinutes();
int sunset = mSunsetTime.transformToMinutes();
Calendar calendar = Calendar.getInstance(Locale.getDefault());
int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
int currentMinute = calendar.get(Calendar.MINUTE);
int currentTime = currentHour * Time.MINUTES_PER_HOUR + currentMinute;
float ratio = 1.0f * (currentTime - sunrise) / (sunset - sunrise);
ratio = ratio <= 0 ? 0 : (ratio > 1.0f ? 1 : ratio);
ObjectAnimator animator = ObjectAnimator.ofFloat(this, "ratio", 0f, ratio);
animator.setDuration(1500L);
animator.setInterpolator(new LinearInterpolator());
animator.start();
}
}
15
Source : HistoryChartView.java
with Apache License 2.0
from Horrarndoo
with Apache License 2.0
from Horrarndoo
/**
* 历史记录查询图表 基于pathMeasure+DashPathEffect+属性动画实现
* 绘制时采取双缓冲绘制
*
* @author zyw
* @creation 2017-03-06
*/
public clreplaced HistoryChartView extends View {
private String TAG = "HistoryChartView";
TypedArray ta;
private float MarginTop = 100;
private float MarginBottom = 100;
private float MarginLeft = 100;
private float MarginRight = 100;
private float mYLabelSize = 50;
private float mXlabelSize = 35;
private float mXUnitTextSize;
private float mYUnitTextSize;
// 圆半径
private int circleRadius = 8;
private int lineStrokeWidth = 3;
private int dataStrokeWidth = 3;
private static final long ANIM_DURATION = 1500;
private PathMeasure mRoomTempPathMeasure;
private PathMeasure mTargetTempPathMeasure;
private Path mRoomTempPath;
private Path mTargetTempPath;
private Paint mBmpPaint;
/**
* 柱形绘制进度
*/
private float mRectFration;
// X,Y轴的单位长度
private float Xscale = 20;
private float Yscale = 20;
// 绘制X轴总长度
private float xLength;
// 绘制Y轴总长度
private float yLength;
// X轴第1个节点的偏移位置
private float xFirstPointOffset;
// y轴显示的节点间隔距离
private int yScaleForData = 1;
// x轴显示的节点间隔距离
private int xScaleForData = 1;
// 画线颜色
private int lineColor;
private int roomTempLineColor;
private int targetTempLineColor;
private int powerTimeLineColor;
private int mUnitColor;
private String mXUnitText;
private String mY1UnitText;
private String mY2UnitText;
// 从Activity传过来的模式值 1:天 2:周 3:月 4:年
private int mMode = 1;
// 原点坐标
private float Xpoint;
private float Ypoint;
// X,Y轴上面的显示文字
private String[] Xlabel = { "1", "2", "3", "4", "5", "6", "7" };
private String[] Ylabel = { "0", "9", "18", "27", "36" };
private String[] Ylabel2 = { "0", "25", "50", "75", "100" };
private final static int X_SCALE_FOR_DATA_DAY = 2;
private final static int X_SCALE_FOR_DATA_WEEK = 1;
private final static int X_SCALE_FOR_DATA_YEAR = 1;
private final static int X_SCALE_FOR_DATA_MOUNTH = 5;
private final static int DAY_MODE = 0;
private final static int WEEK_MODE = 1;
private final static int MONTH_MODE = 2;
private final static int YEAR_MODE = 3;
// 曲线数据
private float[] roomTempDataArray = { 15, 15, 15, 15, 15, 15, 15 };
private float[] targetTempDataArray = { 16, 16, 16, 16, 16, 16, 16 };
private float[] powerOnTimeDataArray = { 100, 100, 100, 100, 100, 100, 100 };
/**
* 各条柱形图当前top值数组
*/
private Float[] rectCurrentTops;
private ValueAnimator mValueAnimator;
private Paint linePaint;
private Paint targetTempPaint;
private Paint roomTempPaint;
private PathEffect mRoomTempEffect;
private PathEffect mtargetTempEffect;
// 定义一个内存中的图片,该图片将作为缓冲区
Bitmap mCacheBitmap = null;
// 定义cacheBitmap上的Canvas对象
Canvas mCacheCanvas = null;
public HistoryChartView(Context context, String[] xlabel, String[] ylabel, float[] roomDataArray) {
super(context);
this.Xlabel = xlabel;
this.Ylabel = ylabel;
this.roomTempDataArray = roomDataArray;
}
public HistoryChartView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// Logger.e("HistoryChartView(Context context, AttributeSet attrs, int defStyleAttr)");
ta = context.obtainStyledAttributes(attrs, R.styleable.HistoryChartView);
setDefaultAttrrbutesValue();
initPaint();
initData();
initParams();
initPath();
ta.recycle();
}
public HistoryChartView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public HistoryChartView(Context context) {
this(context, null);
}
/**
* 设置显示数据
*
* @param strAlldata 历史数据全状态
* @param mode 历史数据模式
*/
public void setData(String strAlldata, int mode) {
// Logger.e("history chart view strAlldata = " + strAlldata);
String[] allHistroyArray = strAlldata.split("-");
String[] arrayRoomTempData = allHistroyArray[0].split(",");
String[] arraySetTempData = allHistroyArray[1].split(",");
String[] arrayPowerTimeData = allHistroyArray[2].split(",");
mMode = mode;
initXData(arrayRoomTempData);
initRoomTempData(arrayRoomTempData);
initTargetTempData(arraySetTempData);
initPowerOnTimeData(arrayPowerTimeData);
initData();
initParams();
initPath();
startAnimation();
}
private void initPaint() {
linePaint = new Paint();
linePaint.setStyle(Paint.Style.STROKE);
linePaint.setAntiAlias(true);
linePaint.setColor(lineColor);
linePaint.setDither(true);
linePaint.setStrokeWidth(lineStrokeWidth);
roomTempPaint = new Paint();
roomTempPaint.setStyle(Paint.Style.STROKE);
roomTempPaint.setAntiAlias(true);
roomTempPaint.setColor(roomTempLineColor);
roomTempPaint.setDither(true);
roomTempPaint.setStrokeWidth(dataStrokeWidth);
targetTempPaint = new Paint();
targetTempPaint.setStyle(Paint.Style.STROKE);
targetTempPaint.setAntiAlias(true);
targetTempPaint.setColor(targetTempLineColor);
targetTempPaint.setDither(true);
targetTempPaint.setStrokeWidth(dataStrokeWidth);
mBmpPaint = new Paint();
}
/**
* 初始化数据
*/
private void initData() {
mRoomTempPath = new Path();
mTargetTempPath = new Path();
rectCurrentTops = new Float[roomTempDataArray.length];
}
/**
* 初始化宽高比例等数据
*/
public void initParams() {
// LogUtils.error(TAG, "initParams");
Xpoint = MarginLeft;
xLength = this.getWidth() - MarginLeft - MarginRight - (MarginRight + MarginLeft) / 16;
yLength = this.getHeight() - MarginTop - MarginBottom;
Ypoint = this.getHeight() - MarginBottom + mYLabelSize / 3;
Xscale = (xLength - xFirstPointOffset * 2) / (this.Xlabel.length - 1);
Yscale = yLength / (this.Ylabel.length - 1);
}
/**
* 初始化path
*/
private void initPath() {
initRoomTempPath(roomTempDataArray);
initTargetTempPath(targetTempDataArray);
}
/**
* 初始化设定温度数据
*
* @param arraySetTempData 设定温度数据
*/
private void initTargetTempData(String[] arraySetTempData) {
targetTempDataArray = new float[arraySetTempData.length];
for (int i = 0; i < arraySetTempData.length; i++) {
if (arraySetTempData[i].length() > 0) {
targetTempDataArray[i] = Float.parseFloat(arraySetTempData[i]);
}
}
}
/**
* 初始化房间温度数据
*
* @param arrayRoomTempData 房间温度数据
*/
private void initRoomTempData(String[] arrayRoomTempData) {
roomTempDataArray = new float[arrayRoomTempData.length];
for (int i = 0; i < arrayRoomTempData.length; i++) {
if (arrayRoomTempData[i].length() > 0) {
roomTempDataArray[i] = Float.parseFloat(arrayRoomTempData[i]);
// LogUtils.error(TAG, "" + roomTempDataArray[i]);
}
}
}
/**
* 初始化开机时间数据
*
* @param arrayPowerTimeData 开机时间数据
*/
private void initPowerOnTimeData(String[] arrayPowerTimeData) {
powerOnTimeDataArray = new float[arrayPowerTimeData.length];
for (int i = 0; i < arrayPowerTimeData.length; i++) {
if (arrayPowerTimeData[i].length() > 0) {
powerOnTimeDataArray[i] = Float.parseFloat(arrayPowerTimeData[i]);
}
}
}
/**
* 初始化X轴数据
*/
private void initXData(String[] tempData) {
switch(mMode) {
case DAY_MODE:
xScaleForData = X_SCALE_FOR_DATA_DAY;
setXUnitText(getResources().getString(R.string.history_x_unit_hour));
break;
case WEEK_MODE:
xScaleForData = X_SCALE_FOR_DATA_WEEK;
setXUnitText(getResources().getString(R.string.history_x_unit_day));
break;
case MONTH_MODE:
xScaleForData = X_SCALE_FOR_DATA_MOUNTH;
setXUnitText(getResources().getString(R.string.history_x_unit_day));
break;
case YEAR_MODE:
xScaleForData = X_SCALE_FOR_DATA_YEAR;
setXUnitText(getResources().getString(R.string.history_x_unit_month));
break;
default:
break;
}
Xlabel = new String[tempData.length];
for (int i = 0; i < Xlabel.length; i++) {
Xlabel[i] = Integer.toString(i + 1);
}
}
private void setDefaultAttrrbutesValue() {
float MarginTopPx = ta.getDimension(R.styleable.HistoryChartView_margin_top, 50);
float MarginBottomPx = ta.getDimension(R.styleable.HistoryChartView_margin_bottom, 50);
float MarginLeftPx = ta.getDimension(R.styleable.HistoryChartView_margin_left, 50);
float MarginRightPx = ta.getDimension(R.styleable.HistoryChartView_margin_right, 50);
float yLabelSizePx = ta.getDimension(R.styleable.HistoryChartView_ylabel_text_size, 30);
float xlabelSizePx = ta.getDimension(R.styleable.HistoryChartView_xlabel_text_size, 20);
float xUnitSizePx = ta.getDimension(R.styleable.HistoryChartView_x_unit_text_size, 30);
float yUnitSizePx = ta.getDimension(R.styleable.HistoryChartView_y_unit_text_size, 30);
float xFirstPointOffsetPx = ta.getDimension(R.styleable.HistoryChartView_x_first_point_offset, 30);
float lineStrokeWidthPx = ta.getDimension(R.styleable.HistoryChartView_line_stroke_width, 5);
float dataStrokeWidthPx = ta.getDimension(R.styleable.HistoryChartView_data_stroke_width, 5);
float circleRadiusPx = ta.getDimension(R.styleable.HistoryChartView_circle_radius, 6);
xFirstPointOffset = DisplayUtils.px2sp(xFirstPointOffsetPx);
MarginTop = DisplayUtils.px2dp(MarginTopPx);
MarginBottom = DisplayUtils.px2dp(MarginBottomPx);
MarginLeft = DisplayUtils.px2dp(MarginLeftPx);
MarginRight = DisplayUtils.px2dp(MarginRightPx);
mYLabelSize = DisplayUtils.px2sp(yLabelSizePx);
mXlabelSize = DisplayUtils.px2sp(xlabelSizePx);
mXUnitTextSize = DisplayUtils.px2sp(xUnitSizePx);
mYUnitTextSize = DisplayUtils.px2sp(yUnitSizePx);
lineStrokeWidth = DisplayUtils.px2sp(lineStrokeWidthPx);
dataStrokeWidth = DisplayUtils.px2sp(dataStrokeWidthPx);
circleRadius = DisplayUtils.px2sp(circleRadiusPx);
lineColor = ta.getColor(R.styleable.HistoryChartView_line_color, getResources().getColor(R.color.light_yellow));
roomTempLineColor = ta.getColor(R.styleable.HistoryChartView_first_data_line_color, getResources().getColor(R.color.indoor_temp));
targetTempLineColor = ta.getColor(R.styleable.HistoryChartView_second_data_line_color, getResources().getColor(R.color.setpoint_temp));
powerTimeLineColor = ta.getColor(R.styleable.HistoryChartView_rect_background_color, getResources().getColor(R.color.power_time));
mUnitColor = ta.getColor(R.styleable.HistoryChartView_unit_color, getResources().getColor(R.color.light_grey));
mXUnitText = ta.getString(R.styleable.HistoryChartView_x_unit_text);
mY1UnitText = ta.getString(R.styleable.HistoryChartView_y1_unit_text);
mY2UnitText = ta.getString(R.styleable.HistoryChartView_y2_unit_text);
}
/**
* 设置X轴单位符号
*
* @param xUnit x轴单位符号
*/
public void setXUnitText(String xUnit) {
mXUnitText = xUnit;
}
/**
* 绘制单位符号
*
* @param canvas canvas
*/
private void drawUnit(Canvas canvas) {
Paint p = new Paint();
p.setAntiAlias(true);
p.setStrokeWidth(dataStrokeWidth);
p.setColor(mUnitColor);
drawXUnit(canvas, p);
drawY1Unit(canvas, p);
drawY2Unit(canvas, p);
}
// 画横轴
private void drawXLine(Canvas canvas, Paint p) {
p.setColor(getResources().getColor(R.color.light_yellow));
canvas.drawLine(Xpoint, Ypoint, xLength + MarginLeft, Ypoint, p);
}
// 画灰色横轴
private void drawGreyXLine(Canvas canvas, Paint p) {
p.setColor(getResources().getColor(R.color.grey_line));
float startX = Xpoint + MarginLeft / 4;
// 纵向
for (int i = yScaleForData; (yLength - i * Yscale) >= 0; i += yScaleForData) {
float startY = Ypoint - i * Yscale;
canvas.drawLine(startX - MarginLeft / 4, startY, xLength + MarginLeft, startY, p);
}
}
// 画数据
private void drawData(Canvas canvas, float[] data, int dataColor) {
Paint p = new Paint();
p.setAntiAlias(true);
p.setStrokeWidth(dataStrokeWidth);
p.setTextSize(mXlabelSize);
// 横向
for (int i = 0; i < Xlabel.length; i++) {
int xLableInt = Integer.parseInt(Xlabel[i]);
float startX = Xpoint + i * Xscale + xFirstPointOffset;
if (xLableInt % xScaleForData == 0) {
p.setColor(lineColor);
canvas.drawText(this.Xlabel[i], startX - mXlabelSize / 3, Ypoint + mXlabelSize * 3 / 2, p);
}
p.setColor(dataColor);
canvas.drawCircle(startX, getDataY(data[i], Ylabel), circleRadius, p);
}
p.setTextSize(mYLabelSize);
// 纵向
for (int i = 0; (yLength - i * Yscale) >= 0; i += yScaleForData) {
p.setColor(lineColor);
canvas.drawText(this.Ylabel[i], MarginLeft / 4, getDataY(Float.valueOf(Ylabel[i]), Ylabel) + mYLabelSize / 3, p);
canvas.drawText(this.Ylabel2[i], this.getWidth() - MarginLeft, getDataY(Float.valueOf(Ylabel2[i]), Ylabel2) + mYLabelSize / 3, p);
}
}
// 获取room temp绘线Path数据
private void initRoomTempPath(float[] data) {
mRoomTempPath.reset();
// Path path = new Path();
float pointX;
float pointY;
// 横向
mRoomTempPath.moveTo(Xpoint + xFirstPointOffset, getDataY(data[0], Ylabel));
mRoomTempPath.moveTo(Xpoint + xFirstPointOffset, getDataY(data[0], Ylabel));
for (int i = 0; i < Xlabel.length; i++) {
float startX = Xpoint + i * Xscale + xFirstPointOffset;
// 绘制数据连线
if (i != 0) {
pointX = Xpoint + (i - 1) * Xscale + xFirstPointOffset;
pointY = getDataY(data[i - 1], Ylabel);
mRoomTempPath.lineTo(pointX, pointY);
}
if (i == Xlabel.length - 1) {
pointX = startX;
pointY = getDataY(data[i], Ylabel);
mRoomTempPath.lineTo(pointX, pointY);
}
}
mRoomTempPathMeasure = new PathMeasure(mRoomTempPath, false);
}
/**
* 获取target temp绘线Path数据
*
* @param data target temp绘线Path数据
*/
private void initTargetTempPath(float[] data) {
mTargetTempPath.reset();
float pointX;
float pointY;
// 横向
mTargetTempPath.moveTo(Xpoint + xFirstPointOffset, getDataY(data[0], Ylabel));
for (int i = 0; i < Xlabel.length; i++) {
float startX = Xpoint + i * Xscale + xFirstPointOffset;
// 绘制数据连线
if (i != 0) {
pointX = Xpoint + (i - 1) * Xscale + xFirstPointOffset;
pointY = getDataY(data[i - 1], Ylabel);
mTargetTempPath.lineTo(pointX, pointY);
}
if (i == Xlabel.length - 1) {
pointX = startX;
pointY = getDataY(data[i], Ylabel);
mTargetTempPath.lineTo(pointX, pointY);
}
}
mTargetTempPathMeasure = new PathMeasure(mTargetTempPath, false);
}
// 绘制矩形图
private void drawRect(Canvas canvas, float[] data, int dataColor) {
Paint p = new Paint();
float left;
float top;
float right;
float bottom;
float stopY = getDataY(Float.parseFloat(Ylabel[Ylabel.length - 1]), // 灰色线Y轴位置
Ylabel);
float rectYScale = (Ypoint - stopY) / 100;
p.setAntiAlias(true);
p.setStrokeWidth(dataStrokeWidth);
p.setColor(dataColor);
// 横向
for (int i = 0; i < Xlabel.length; i++) {
// 绘制柱形图
if (i != 0) {
left = Xpoint + (i - 1) * Xscale + xFirstPointOffset + Xscale / 6;
// 要绘制的rect最终top值
top = Ypoint - data[i - 1] * rectYScale + lineStrokeWidth;
// 起点top + (起点top - 终点top) * mRectFration
// 根据fraction动态更新top值
rectCurrentTops[i] = Ypoint - (Ypoint - top) * mRectFration;
right = left + Xscale * 4 / 6;
bottom = Ypoint;
//
canvas.drawRect(left, rectCurrentTops[i], right, bottom, p);
// 每次valueAnimator更新时重绘最新top值
}
}
}
private void drawY1Unit(Canvas canvas, Paint p) {
int maxYLabelValue = Integer.valueOf(Ylabel[Ylabel.length - 1]);
p.setTextSize(mYUnitTextSize);
float textWidth = p.measureText(mY1UnitText);
canvas.drawText(mY1UnitText, MarginLeft / 2 - textWidth / 2, getDataY(maxYLabelValue, Ylabel) - mYLabelSize - mYLabelSize / 5, p);
}
private void drawY2Unit(Canvas canvas, Paint p) {
int maxYLabel2Value = Integer.valueOf(Ylabel2[Ylabel2.length - 1]);
p.setTextSize(mYUnitTextSize);
float textWidth = p.measureText(mY2UnitText);
canvas.drawText(mY2UnitText, this.getWidth() - MarginRight / 2 - textWidth * 3 / 4, getDataY(maxYLabel2Value, Ylabel2) - mYLabelSize - mYLabelSize / 5, p);
}
private void drawXUnit(Canvas canvas, Paint p) {
p.setTextSize(mXUnitTextSize);
float textWidth = p.measureText(mXUnitText);
canvas.drawText(mXUnitText, this.getWidth() / 2 - textWidth / 2, Ypoint + mXlabelSize * 3 + mXlabelSize / 5, p);
}
/**
* 获取data对应绘制Y点值
*/
private float getDataY(float dataY, String[] Ylabel) {
float y0 = 0;
float y1 = 0;
try {
y0 = Float.parseFloat(Ylabel[0]);
y1 = Float.parseFloat(Ylabel[1]);
} catch (Exception e) {
return 0;
}
try {
return Ypoint - ((dataY - y0) * Yscale / (y1 - y0));
} catch (Exception e) {
return 0;
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
// LogUtils.error(TAG, "onLayout");
initParams();
if (onViewLayoutListener != null) {
onViewLayoutListener.onLayoutSuccess();
}
// 创建一个与该View相同大小的缓冲区
mCacheBitmap = Bitmap.createBitmap(this.getWidth(), this.getHeight(), Bitmap.Config.ARGB_8888);
mCacheCanvas = new Canvas();
// 设置cacheCanvas将会绘制到内存中cacheBitmap上
mCacheCanvas.setBitmap(mCacheBitmap);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mCacheCanvas.drawColor(Color.BLACK);
drawGreyXLine(mCacheCanvas, linePaint);
drawUnit(mCacheCanvas);
if (powerOnTimeDataArray.length > 1) {
drawRect(mCacheCanvas, powerOnTimeDataArray, powerTimeLineColor);
}
mCacheCanvas.drawPath(mRoomTempPath, roomTempPaint);
if (roomTempDataArray.length > 1) {
drawData(mCacheCanvas, roomTempDataArray, roomTempLineColor);
}
mCacheCanvas.drawPath(mTargetTempPath, targetTempPaint);
if (targetTempDataArray.length > 1) {
drawData(mCacheCanvas, targetTempDataArray, targetTempLineColor);
}
drawXLine(mCacheCanvas, linePaint);
// 将cacheBitmap绘制到该View组件
canvas.drawBitmap(mCacheBitmap, 0, 0, mBmpPaint);
}
/**
* 开启动画
*/
private void startAnimation() {
if (mValueAnimator != null) {
mValueAnimator.cancel();
}
final float targetTempLength = mTargetTempPathMeasure.getLength();
final float roomTempLength = mRoomTempPathMeasure.getLength();
mValueAnimator = ValueAnimator.ofFloat(1, 0);
mValueAnimator.setDuration(ANIM_DURATION);
// 减速插值器
mValueAnimator.setInterpolator(new DecelerateInterpolator());
mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float fraction = (Float) animation.getAnimatedValue();
// 更新mtargetTempEffect
mtargetTempEffect = new DashPathEffect(new float[] { targetTempLength, targetTempLength }, fraction * targetTempLength);
targetTempPaint.setPathEffect(mtargetTempEffect);
// 更新mRoomTempEffect
mRoomTempEffect = new DashPathEffect(new float[] { roomTempLength, roomTempLength }, fraction * roomTempLength);
roomTempPaint.setPathEffect(mRoomTempEffect);
// 更新rect绘制fraction进度
// fraction是1->0 我们需要的柱形图绘制比例是0->1
mRectFration = 1 - fraction;
postInvalidate();
}
});
mValueAnimator.start();
}
public interface OnViewLayoutListener {
void onLayoutSuccess();
}
public void setOnViewLayoutListener(OnViewLayoutListener onViewLayoutListener) {
this.onViewLayoutListener = onViewLayoutListener;
}
private OnViewLayoutListener onViewLayoutListener;
}
15
Source : BindNormalActivity.java
with MIT License
from CarGuo
with MIT License
from CarGuo
public void init() {
normalAdapterManager = new BindSuperAdapterManager();
normalAdapterManager.bind(BindImageModel.clreplaced, BindImageHolder.ID, BindImageHolder.clreplaced).bind(BindTextModel.clreplaced, BindTextHolder.ID, BindTextHolder.clreplaced).bind(BindMutliModel.clreplaced, BindMutliHolder.ID, BindMutliHolder.clreplaced).bind(BindClickModel.clreplaced, BindClickHolder.ID, BindClickHolder.clreplaced).bindEmpty(BindNoDataHolder.NoDataModel.clreplaced, BindNoDataHolder.ID, BindNoDataHolder.clreplaced).setNeedAnimation(true).setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(Context context, int position) {
Toast.makeText(context, "点击了!! " + position, Toast.LENGTH_SHORT).show();
}
});
adapter = new BindRecyclerAdapter(this, normalAdapterManager, datas);
recycler.setLayoutManager(new LinearLayoutManager(this));
// 间隔线
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(getResources().getColor(R.color.material_deep_teal_200));
PathEffect effects = new DashPathEffect(new float[] { 5, 5, 5, 5 }, 1);
paint.setPathEffect(effects);
paint.setStrokeWidth(dip2px(this, 5));
recycler.addItemDecoration(new BindDecorationBuilder(adapter).setPaint(paint).setSpace(dip2px(this, 5)).builder());
recycler.setAdapter(adapter);
}
15
Source : CustomClickTopicSpan.java
with MIT License
from CarGuo
with MIT License
from CarGuo
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(true);
ds.setStyle(Paint.Style.FILL_AND_STROKE);
PathEffect effects = new DashPathEffect(new float[] { 1, 1 }, 1);
ds.setPathEffect(effects);
ds.setStrokeWidth(2);
}
15
Source : CustomClickAtUserSpan.java
with MIT License
from CarGuo
with MIT License
from CarGuo
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(true);
// 间隔线
ds.setStyle(Paint.Style.STROKE);
PathEffect effects = new DashPathEffect(new float[] { 1, 1 }, 1);
ds.setPathEffect(effects);
ds.setStrokeWidth(5);
}
15
Source : WindView.java
with Apache License 2.0
from AhmadNemati
with Apache License 2.0
from AhmadNemati
/**
* Created by َAhmad Nemati on 12/19/2016.
*/
public clreplaced WindView extends View {
private static final String TAG = WindView.clreplaced.getSimpleName();
private Rect rect = new Rect();
private Path path;
private Matrix matrix;
private Paint paint;
private int textColor;
private String WindDirectionText;
private long startTime = 0;
private PathEffect pathEffect;
private Bitmap smallPoleBitmap;
private Bitmap bigPoleBitmap;
private Bitmap smallBladeBitmap;
private Bitmap bigBladeBitmap;
private Bitmap trendBitmap;
private float rotation;
private int bigPoleX;
private int smallPoleX;
private String windText = "Wind";
private String windName;
private String windSpeedText;
private String barometerText = "Barometer";
private int poleBottomY;
private int windTextX;
private int windTextY;
private float windSpeed;
private String windSpeedUnit;
private boolean animationEnable = true;
private boolean animationBaroMeterEnable = false;
private float pressurePaddingTop;
private double senterOfPressureLine;
private double pressureLineSize;
private int scale;
private float barometerTickSpacing;
private double lineSpace;
private float pressure;
private String pressureText;
private float lineSize;
private float curSize;
private int pressureTextY;
private String pressureUnit;
private int labelFontSize;
private int numericFontSize;
private Typeface typeface;
private String empty = "--";
private TrendType trendType = TrendType.UP;
private int lineColor = Color.WHITE;
private float lineStrokeWidth = 1f;
private int barometerColor = Color.WHITE;
private float barometerStrokeWidth = 2f;
public WindView(Context context) {
super(context);
setupView();
}
public WindView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public WindView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public WindView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(attrs);
}
public static String getTAG() {
return TAG;
}
private void init(AttributeSet attrs) {
TypedArray obtainStyledAttributes = getContext().obtainStyledAttributes(attrs, R.styleable.WindView);
pressure = obtainStyledAttributes.getFloat(R.styleable.WindView_pressure, -1.0f);
windTextX = obtainStyledAttributes.getDimensionPixelSize(R.styleable.WindView_windTextX, 242);
windTextY = obtainStyledAttributes.getDimensionPixelSize(R.styleable.WindView_windTextY, 44);
pressureTextY = obtainStyledAttributes.getDimensionPixelSize(R.styleable.WindView_pressureTextY, 8);
labelFontSize = obtainStyledAttributes.getDimensionPixelSize(R.styleable.WindView_labelFontSize, 18);
numericFontSize = obtainStyledAttributes.getDimensionPixelSize(R.styleable.WindView_numericFontSize, 14);
barometerTickSpacing = (float) obtainStyledAttributes.getDimensionPixelSize(R.styleable.WindView_barometerTickSpacing, 9);
bigPoleX = obtainStyledAttributes.getDimensionPixelSize(R.styleable.WindView_bigPoleX, 48);
smallPoleX = obtainStyledAttributes.getDimensionPixelSize(R.styleable.WindView_smallPoleX, 98);
poleBottomY = obtainStyledAttributes.getDimensionPixelSize(R.styleable.WindView_poleBottomY, 118);
scale = getScaleInPixel(20);
obtainStyledAttributes.recycle();
setupView();
}
private void setupView() {
Resources resources = getContext().getResources();
textColor = resources.getColor(R.color.text_color);
paint = new Paint();
paint.setAntiAlias(true);
paint.setTypeface(getTypeface());
paint.setStyle(Paint.Style.FILL);
smallPoleBitmap = BitmapFactory.decodeResource(resources, R.drawable.smallpole);
bigPoleBitmap = BitmapFactory.decodeResource(resources, R.drawable.bigpole);
smallBladeBitmap = BitmapFactory.decodeResource(resources, R.drawable.smallblade);
bigBladeBitmap = BitmapFactory.decodeResource(resources, R.drawable.bigblade);
matrix = new Matrix();
WindDirectionText = "";
lineColor = Color.parseColor("#8bece8e8");
rotation = 0.0f;
lineSpace = toPixel(1d);
pressureLineSize = lineSpace + (barometerTickSpacing);
senterOfPressureLine = (9d * pressureLineSize) + lineSpace;
pressurePaddingTop = getPaddingTop();
pathEffect = new DashPathEffect(new float[] { 4f, 4f }, 0f);
}
public void start() {
animationEnable = true;
invalidate();
}
public void stop() {
animationEnable = false;
}
public void setWindSpeed(float f) {
windSpeed = f;
if (windSpeed >= 36.0f && animationEnable) {
if (smallBladeBitmap != null) {
smallBladeBitmap.recycle();
}
if (bigBladeBitmap != null) {
bigBladeBitmap.recycle();
}
smallBladeBitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.blade_s_blur);
bigBladeBitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.blade_big_blur);
}
windSpeedText = formatFloat(windSpeed);
initSpeedUnit();
invalidate();
}
public void setWindDirection(String str) {
WindDirectionText = str;
initSpeedUnit();
}
private void initSpeedUnit() {
StringBuilder stringBuilder = new StringBuilder();
if (windSpeed < 0.0f || windSpeedUnit == null) {
stringBuilder.append(empty);
} else {
stringBuilder.append(" ").append(windSpeedUnit).append(" ").append(WindDirectionText);
}
windName = stringBuilder.toString();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
setupPressureLine(false);
}
@Override
protected void onDraw(Canvas canvas) {
initCanvas(canvas);
}
private void initCanvas(Canvas canvas) {
boolean enable = false;
if (bigPoleBitmap != null && smallBladeBitmap != null && bigBladeBitmap != null) {
paint.setColor(textColor);
paint.setTypeface(typeface);
canvas.drawBitmap(bigPoleBitmap, bigPoleX, (poleBottomY - bigPoleBitmap.getHeight()), paint);
canvas.drawBitmap(smallPoleBitmap, smallPoleX, (poleBottomY - smallPoleBitmap.getHeight()), paint);
if (animationEnable) {
startTimes();
}
int width = bigPoleX + (bigPoleBitmap.getWidth() / 2);
int height = (poleBottomY - bigPoleBitmap.getHeight()) - 4;
rect.left = width - (bigBladeBitmap.getWidth() / 2);
rect.top = height - (bigBladeBitmap.getHeight() / 2);
rect.bottom = (bigBladeBitmap.getHeight() / 2) + height;
matrix.reset();
matrix.setRotate(rotation, (bigBladeBitmap.getWidth()) / 2.0f, (bigBladeBitmap.getHeight()) / 2.0f);
matrix.postTranslate((width - (bigBladeBitmap.getWidth() / 2)), (height - (bigBladeBitmap.getHeight() / 2)));
canvas.drawBitmap(bigBladeBitmap, matrix, paint);
width = smallPoleX + (smallPoleBitmap.getWidth() / 2);
int height2 = (poleBottomY - smallPoleBitmap.getHeight()) - 4;
rect.right = (smallBladeBitmap.getWidth() / 2) + width;
rect.bottom = Math.max(rect.bottom, height + (smallBladeBitmap.getHeight() / 2));
matrix.reset();
matrix.setRotate(rotation, (smallBladeBitmap.getWidth()) / 2.0f, (smallBladeBitmap.getHeight()) / 2.0f);
matrix.postTranslate((width - (smallBladeBitmap.getWidth() / 2)), (height2 - (smallBladeBitmap.getHeight() / 2)));
canvas.drawBitmap(smallBladeBitmap, matrix, paint);
drawWind(canvas);
drawBarometer(canvas);
if (!animationEnable) {
curSize = lineSize;
}
drawLine(canvas);
drawPressure(canvas);
if (trendType == TrendType.DOWN && curSize < lineSize && animationBaroMeterEnable) {
curSize += 1.0f;
enable = true;
} else if (trendType == TrendType.UP && curSize > lineSize && animationBaroMeterEnable) {
curSize -= 1.0f;
enable = true;
} else {
animationBaroMeterEnable = false;
}
if ((animationEnable && windSpeed > 0.0f) || enable) {
invalidate();
}
}
}
private void drawLine(Canvas canvas) {
paint.setColor(lineColor);
paint.setStrokeWidth(lineStrokeWidth);
paint.setStyle(Paint.Style.STROKE);
paint.setPathEffect(pathEffect);
float width = (float) getWidth();
if (path == null) {
path = new Path();
} else {
path.reset();
}
path.moveTo(10.0f, curSize);
path.quadTo(width / 2.0f, curSize, width - 20.0f, curSize);
canvas.drawPath(path, paint);
paint.setStyle(Paint.Style.FILL);
paint.setPathEffect(null);
paint.setColor(textColor);
}
private void setupPressureLine(boolean z) {
int height = getHeight();
if (height > 0) {
if ((senterOfPressureLine + (getPaddingTop())) + (getPaddingBottom()) >= (height)) {
senterOfPressureLine = ((height - getPaddingTop()) - getPaddingBottom());
pressureLineSize = senterOfPressureLine / 10.0d;
}
pressurePaddingTop = (float) ((((height - getPaddingTop()) / 2)) - (senterOfPressureLine / 2.0d));
float f = (float) (((pressurePaddingTop) + (pressureLineSize * 5.0d)) + lineSpace);
if (z) {
lineSize = f;
curSize = lineSize;
} else if (trendType == TrendType.DOWN) {
lineSize = (float) (((pressurePaddingTop) + (pressureLineSize * 5.0d)) + lineSpace);
if (animationBaroMeterEnable) {
curSize = (float) (((pressurePaddingTop) + (pressureLineSize * 7.0d)) + lineSpace);
} else {
curSize = lineSize;
}
trendBitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.trend_falling);
} else if (trendType == TrendType.UP) {
lineSize = (float) (((pressurePaddingTop) + (pressureLineSize * 5.0d)) + lineSpace);
if (animationBaroMeterEnable) {
curSize = (float) (((pressurePaddingTop) + (pressureLineSize * 7.0d)) + lineSpace);
} else {
curSize = lineSize;
}
trendBitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.trend_rising);
} else {
lineSize = f;
curSize = lineSize;
if (trendBitmap != null) {
trendBitmap.recycle();
trendBitmap = null;
}
}
}
}
private void drawWind(Canvas canvas) {
paint.setTextSize(labelFontSize);
paint.setStyle(Paint.Style.FILL);
paint.setPathEffect(null);
float width = (((smallPoleX) + ((smallBladeBitmap.getWidth()) / 2.0f)) + windTextX);
canvas.drawText(windText, width, windTextY, paint);
if (windSpeed < 0.0f) {
paint.setTextSize(labelFontSize);
canvas.drawText(windName, width, (windTextY + labelFontSize), paint);
} else if (!stringValid(windSpeedText)) {
paint.setTextSize(numericFontSize);
canvas.drawText(windSpeedText, width, (windTextY + numericFontSize), paint);
if (!stringValid(windName)) {
paint.setTextSize(labelFontSize);
canvas.drawText(windName, width + (((windSpeedText.length() * numericFontSize)) / 2.0f), (windTextY + numericFontSize), paint);
}
}
}
private void drawPressure(Canvas canvas) {
float f = curSize + (pressureTextY);
int width = (getWidth() - 14) - scale;
paint.setTextSize(labelFontSize);
float measureText = (width - (paint.measureText(barometerText)));
f += labelFontSize;
canvas.drawText(barometerText, measureText, f, paint);
if (trendBitmap != null) {
canvas.drawBitmap(trendBitmap, (measureText - (trendBitmap.getWidth())) - 4.0f, f - ((labelFontSize / 2)), paint);
}
if (!TextUtils.isEmpty(pressureUnit)) {
paint.setTextSize((float) labelFontSize);
measureText = (float) (width - ((int) paint.measureText(pressureUnit)));
f += (float) numericFontSize;
canvas.drawText(pressureUnit, measureText, f, paint);
}
if (!TextUtils.isEmpty(pressureText)) {
paint.setTextSize((float) numericFontSize);
canvas.drawText(pressureText, measureText - ((((paint.measureText(pressureText)) + 4)) + ((paint.measureText(" ")))), f, paint);
}
}
private void startTimes() {
long nanoTime = System.nanoTime();
float f = ((float) (nanoTime - startTime)) / 1000000.0f;
startTime = nanoTime;
rotation = ((float) ((Math.sqrt((double) windSpeed) * (f)) / 20.0d)) + rotation;
rotation %= 360.0f;
}
private void drawBarometer(Canvas canvas) {
paint.setStrokeWidth(barometerStrokeWidth);
paint.setColor(barometerColor);
paint.setStyle(Paint.Style.FILL);
int width = getWidth();
float f = pressurePaddingTop;
for (int i = 0; i < 10; i++) {
canvas.drawLine((float) ((width) - toPixel(5d)), f, width, f, paint);
f = (float) ((f) + (lineSpace + (barometerTickSpacing)));
}
paint.setColor(textColor);
}
public void animateBaroMeter() {
if (!animationBaroMeterEnable) {
animationBaroMeterEnable = true;
setupPressureLine(false);
invalidate();
}
}
private int getScaleInPixel(int i) {
return (int) ((getContext().getResources().getDisplayMetrics().density * (i)) + 0.5f);
}
private int dpToPx(int dp) {
Resources r = getResources();
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics());
}
private double toPixel(double d) {
return (getContext().getResources().getDisplayMetrics().density) * d;
}
private String formatFloat(float f) {
try {
return NumberFormat.getInstance().format(f);
} catch (Exception e) {
return empty;
}
}
private float getscale(float f, int i) {
return new BigDecimal(Float.toString(f)).setScale(i, 4).floatValue();
}
private boolean stringValid(String str) {
return str == null || str.trim().length() == 0 || str.trim().equalsIgnoreCase("null");
}
public TrendType getTrendType() {
return trendType;
}
public void setTrendType(TrendType trendType) {
this.trendType = trendType;
setupPressureLine(false);
}
public Typeface getTypeface() {
if (typeface == null)
return Typeface.DEFAULT;
return typeface;
}
public void setTypeface(Typeface typeface) {
this.typeface = typeface;
}
public int getTextColor() {
return textColor;
}
public void setTextColor(int textColor) {
this.textColor = textColor;
}
public int getLineColor() {
return lineColor;
}
public void setLineColor(int lineColor) {
this.lineColor = lineColor;
}
public float getLineStrokeWidth() {
return lineStrokeWidth;
}
public void setLineStrokeWidth(float lineStrokeWidth) {
this.lineStrokeWidth = lineStrokeWidth;
}
public int getBarometerColor() {
return barometerColor;
}
public void setBarometerColor(int barometerColor) {
this.barometerColor = barometerColor;
}
public float getBarometerStrokeWidth() {
return barometerStrokeWidth;
}
public void setBarometerStrokeWidth(float barometerStrokeWidth) {
this.barometerStrokeWidth = barometerStrokeWidth;
}
public String getWindDirectionText() {
return WindDirectionText;
}
public void setWindDirectionText(String windDirectionText) {
WindDirectionText = windDirectionText;
}
public int getBigPoleX() {
return bigPoleX;
}
public void setBigPoleX(int bigPoleX) {
this.bigPoleX = bigPoleX;
}
public int getSmallPoleX() {
return smallPoleX;
}
public void setSmallPoleX(int smallPoleX) {
this.smallPoleX = smallPoleX;
}
public String getWindText() {
return windText;
}
public void setWindText(String windText) {
this.windText = windText;
}
public String getWindName() {
return windName;
}
public void setWindName(String windName) {
this.windName = windName;
}
public String getWindSpeedText() {
return windSpeedText;
}
public void setWindSpeedText(String windSpeedText) {
this.windSpeedText = windSpeedText;
}
public String getBarometerText() {
return barometerText;
}
public void setBarometerText(String barometerText) {
this.barometerText = barometerText;
}
public int getPoleBottomY() {
return poleBottomY;
}
public void setPoleBottomY(int poleBottomY) {
this.poleBottomY = poleBottomY;
}
public int getWindTextX() {
return windTextX;
}
public void setWindTextX(int windTextX) {
this.windTextX = windTextX;
}
public int getWindTextY() {
return windTextY;
}
public void setWindTextY(int windTextY) {
this.windTextY = windTextY;
}
public String getWindSpeedUnit() {
return windSpeedUnit;
}
public void setWindSpeedUnit(String str) {
windSpeedUnit = str;
initSpeedUnit();
}
public Rect getRect() {
return rect;
}
public void setRect(Rect rect) {
this.rect = rect;
}
public int getLabelFontSize() {
return labelFontSize;
}
public void setLabelFontSize(int labelFontSize) {
this.labelFontSize = labelFontSize;
}
public int getNumericFontSize() {
return numericFontSize;
}
public void setNumericFontSize(int numericFontSize) {
this.numericFontSize = numericFontSize;
}
public String getPressureUnit() {
return pressureUnit;
}
public void setPressureUnit(String str) {
pressureUnit = str;
}
public int getPressureTextY() {
return pressureTextY;
}
public void setPressureTextY(int pressureTextY) {
this.pressureTextY = pressureTextY;
}
public float getPressure() {
return pressure;
}
public void setPressure(float f) {
pressure = getscale(f, 2);
if (pressure < 0.0f) {
pressureText = empty;
} else {
pressureText = formatFloat(pressure);
}
}
public float getLineSize() {
return lineSize;
}
public void setLineSize(float lineSize) {
this.lineSize = lineSize;
}
public double getLineSpace() {
return lineSpace;
}
public void setLineSpace(double lineSpace) {
this.lineSpace = lineSpace;
}
}
14
Source : CircleProgressView.java
with Apache License 2.0
from xuexiangjys
with Apache License 2.0
from xuexiangjys
/**
* @author xuexiang
* @since 2019-05-12 12:34
*/
public clreplaced CircleProgressView extends View {
@Retention(RetentionPolicy.SOURCE)
@IntDef({ ACCELERATE_DECELERATE_INTERPOLATOR, LINEAR_INTERPOLATOR, ACCELERATE_INTERPOLATOR, DECELERATE_INTERPOLATOR, OVERSHOOT_INTERPOLATOR })
private @interface AnimateType {
}
/**
* animation types supported
*/
public static final int ACCELERATE_DECELERATE_INTERPOLATOR = 0;
public static final int LINEAR_INTERPOLATOR = 1;
public static final int ACCELERATE_INTERPOLATOR = 2;
public static final int DECELERATE_INTERPOLATOR = 3;
public static final int OVERSHOOT_INTERPOLATOR = 4;
/**
* the type of animation
*/
private int mAnimateType = 0;
/**
* the progress of start point
*/
private float mStartProgress = 0;
/**
* the progress of end point
*/
private float mEndProgress = 60;
/**
* the color of start progress
*/
private int mStartColor = getResources().getColor(R.color.xui_config_color_light_orange);
/**
* the color of end progress
*/
private int mEndColor = getResources().getColor(R.color.xui_config_color_dark_orange);
/**
* has track of moving or not
*/
private boolean trackEnabled;
/**
* filling the inner space or not
*/
private boolean fillEnabled;
/**
* the stroke width of Track
*/
private int mTrackWidth;
/**
* the stroke width of progress
*/
private int mProgressWidth;
/**
* the size of inner text
*/
private int mProgressTextSize;
/**
* the color of inner text
*/
private int mProgressTextColor;
/**
* the circle of progress broken or not
*/
private boolean circleBroken;
/**
* the color of progress track
*/
private int mTrackColor = getResources().getColor(R.color.default_pv_track_color);
/**
* the duration of progress moving
*/
private int mProgressDuration = 1200;
/**
* show the inner text or not
*/
private boolean textVisibility;
/**
* the animator of progress moving
*/
private ObjectAnimator progressAnimator;
/**
* the progress of moving
*/
private float moveProgress = 0;
/**
* the paint of drawing progress
*/
private Paint progressPaint;
/**
* the paint of drawing track
*/
private Paint trackPaint;
/**
* the gradient of color
*/
private LinearGradient mShader;
/**
* the oval's rect shape
*/
private RectF mOval;
private Interpolator mInterpolator;
private CircleProgressUpdateListener mUpdateListener;
/**
* the path of scale zone
*/
private Path mScaleZonePath;
/**
* the width of each scale zone
*/
private float mScaleZoneWidth;
/**
* the length of each scale zone
*/
private float mScaleZoneLength;
/**
* the padding of scale zones
*/
private int mScaleZonePadding;
/**
* open draw the scale zone or not
*/
private boolean isGraduated = false;
/**
* the radius of scale zone corner
*/
private int mScaleZoneCornerRadius = 0;
PathEffect pathEffect;
public CircleProgressView(Context context) {
this(context, null);
}
public CircleProgressView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, R.attr.CircleProgressViewStyle);
}
public CircleProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
obtainAttrs(context, attrs, defStyleAttr);
init();
}
private void obtainAttrs(Context context, AttributeSet attrs, int defStyleAttr) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressView, defStyleAttr, 0);
mStartProgress = typedArray.getInt(R.styleable.CircleProgressView_cpv_start_progress, 0);
mEndProgress = typedArray.getInt(R.styleable.CircleProgressView_cpv_end_progress, 60);
mStartColor = typedArray.getColor(R.styleable.CircleProgressView_cpv_start_color, getResources().getColor(R.color.xui_config_color_light_orange));
mEndColor = typedArray.getColor(R.styleable.CircleProgressView_cpv_end_color, getResources().getColor(R.color.xui_config_color_dark_orange));
fillEnabled = typedArray.getBoolean(R.styleable.CircleProgressView_cpv_isFilled, false);
trackEnabled = typedArray.getBoolean(R.styleable.CircleProgressView_cpv_isTracked, false);
circleBroken = typedArray.getBoolean(R.styleable.CircleProgressView_cpv_circle_broken, false);
mProgressTextColor = typedArray.getColor(R.styleable.CircleProgressView_cpv_progress_textColor, ThemeUtils.resolveColor(getContext(), R.attr.colorAccent));
mProgressTextSize = typedArray.getDimensionPixelSize(R.styleable.CircleProgressView_cpv_progress_textSize, getResources().getDimensionPixelSize(R.dimen.default_pv_progress_text_size));
mTrackWidth = typedArray.getDimensionPixelSize(R.styleable.CircleProgressView_cpv_track_width, getResources().getDimensionPixelSize(R.dimen.default_pv_trace_width));
mProgressWidth = typedArray.getDimensionPixelSize(R.styleable.CircleProgressView_cpv_progress_width, getResources().getDimensionPixelSize(R.dimen.default_pv_trace_width));
mAnimateType = typedArray.getInt(R.styleable.CircleProgressView_cpv_animate_type, ACCELERATE_DECELERATE_INTERPOLATOR);
mTrackColor = typedArray.getColor(R.styleable.CircleProgressView_cpv_track_color, getResources().getColor(R.color.default_pv_track_color));
textVisibility = typedArray.getBoolean(R.styleable.CircleProgressView_cpv_progress_textVisibility, true);
mProgressDuration = typedArray.getInt(R.styleable.CircleProgressView_cpv_progress_duration, 1200);
mScaleZoneLength = typedArray.getDimensionPixelSize(R.styleable.CircleProgressView_cpv_scaleZone_length, getResources().getDimensionPixelSize(R.dimen.default_pv_zone_length));
mScaleZoneWidth = typedArray.getDimensionPixelSize(R.styleable.CircleProgressView_cpv_scaleZone_width, getResources().getDimensionPixelSize(R.dimen.default_pv_zone_width));
mScaleZonePadding = typedArray.getDimensionPixelSize(R.styleable.CircleProgressView_cpv_scaleZone_padding, getResources().getDimensionPixelSize(R.dimen.default_pv_zone_padding));
mScaleZoneCornerRadius = typedArray.getDimensionPixelSize(R.styleable.CircleProgressView_cpv_scaleZone_corner_radius, getResources().getDimensionPixelSize(R.dimen.default_pv_zone_corner_radius));
isGraduated = typedArray.getBoolean(R.styleable.CircleProgressView_cpv_isGraduated, false);
moveProgress = mStartProgress;
typedArray.recycle();
}
private void init() {
progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
progressPaint.setStyle(Paint.Style.STROKE);
progressPaint.setStrokeCap(Paint.Cap.ROUND);
progressPaint.setStrokeWidth(mProgressWidth);
trackPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
trackPaint.setStyle(Paint.Style.STROKE);
trackPaint.setStrokeCap(Paint.Cap.ROUND);
trackPaint.setStrokeWidth(mTrackWidth);
mScaleZonePath = new Path();
drawScaleZones(isGraduated);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawTrack(canvas);
drawProgress(canvas);
drawProgressText(canvas);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
updateTheTrack();
mShader = new LinearGradient(mOval.left - 200, mOval.top - 200, mOval.right + 20, mOval.bottom + 20, mStartColor, mEndColor, Shader.TileMode.CLAMP);
/**
* draw the scale zone shape
*/
/**
* the shape of scale zone
*/
RectF mScaleZoneRect = new RectF(0, 0, mScaleZoneWidth, mScaleZoneLength);
mScaleZonePath.addRoundRect(mScaleZoneRect, mScaleZoneCornerRadius, mScaleZoneCornerRadius, Path.Direction.CW);
}
/**
* draw the track(moving background)
*
* @param canvas mCanvas
*/
private void drawTrack(Canvas canvas) {
if (trackEnabled) {
trackPaint.setShader(null);
trackPaint.setColor(mTrackColor);
initTrack(canvas, fillEnabled);
}
}
private void drawProgress(Canvas canvas) {
progressPaint.setShader(mShader);
updateTheTrack();
initProgressDrawing(canvas, fillEnabled);
}
/**
* draw the each scale zone, you can set round corner fot it
*
* @link
*/
private void drawScaleZones(boolean isGraduated) {
if (isGraduated) {
if (pathEffect == null) {
pathEffect = new PathDashPathEffect(mScaleZonePath, mScaleZonePadding, 0, PathDashPathEffect.Style.ROTATE);
}
progressPaint.setPathEffect(pathEffect);
} else {
pathEffect = null;
progressPaint.setPathEffect(null);
}
}
/**
* init for track view
*
* @param canvas mCanvas
* @param isFilled whether filled or not
*/
private void initTrack(Canvas canvas, boolean isFilled) {
if (isFilled) {
trackPaint.setStyle(Paint.Style.FILL);
} else {
trackPaint.setStyle(Paint.Style.STROKE);
}
if (circleBroken) {
canvas.drawArc(mOval, 135, 270, isFilled, trackPaint);
} else {
canvas.drawArc(mOval, 90, 360, isFilled, trackPaint);
}
}
/**
* draw the progress text
*
* @param canvas mCanvas
*/
private void drawProgressText(Canvas canvas) {
if (textVisibility) {
Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setStyle(Paint.Style.FILL);
mTextPaint.setTextSize(mProgressTextSize);
mTextPaint.setColor(mProgressTextColor);
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setTypeface(XUI.getDefaultTypeface());
String progressText = ((int) moveProgress) + "%";
float x = (getWidth() + getPaddingLeft() - getPaddingRight()) >> 1;
float y = (getHeight() + getPaddingTop() - getPaddingBottom() - (mTextPaint.descent() + mTextPaint.ascent())) / 2;
canvas.drawText(progressText, x, y, mTextPaint);
}
}
/**
* set progress animate type
*
* @param type anim type
*/
public void setAnimateType(@AnimateType int type) {
this.mAnimateType = type;
setObjectAnimatorType(type);
}
/**
* set object animation type by received
*
* @param animatorType object anim type
*/
private void setObjectAnimatorType(int animatorType) {
switch(animatorType) {
case ACCELERATE_DECELERATE_INTERPOLATOR:
if (mInterpolator != null) {
mInterpolator = null;
}
mInterpolator = new AccelerateDecelerateInterpolator();
break;
case LINEAR_INTERPOLATOR:
if (mInterpolator != null) {
mInterpolator = null;
}
mInterpolator = new LinearInterpolator();
break;
case ACCELERATE_INTERPOLATOR:
if (mInterpolator != null) {
mInterpolator = null;
mInterpolator = new AccelerateInterpolator();
}
break;
case DECELERATE_INTERPOLATOR:
if (mInterpolator != null) {
mInterpolator = null;
}
mInterpolator = new DecelerateInterpolator();
break;
case OVERSHOOT_INTERPOLATOR:
if (mInterpolator != null) {
mInterpolator = null;
}
mInterpolator = new OvershootInterpolator();
break;
default:
break;
}
}
/**
* set move progress
*
* @param progress progress of moving
*/
public void setProgress(float progress) {
this.moveProgress = progress;
refreshTheView();
}
public float getProgress() {
return this.moveProgress;
}
/**
* set start progress
*
* @param startProgress start progress
*/
public void setStartProgress(float startProgress) {
if (startProgress < 0 || startProgress > 100) {
throw new IllegalArgumentException("Illegal progress value, please change it!");
}
this.mStartProgress = startProgress;
this.moveProgress = mStartProgress;
refreshTheView();
}
/**
* set end progress
*
* @param endProgress end progress
*/
public void setEndProgress(float endProgress) {
if (endProgress < 0 || endProgress > 100) {
throw new IllegalArgumentException("Illegal progress value, please change it!");
}
this.mEndProgress = endProgress;
refreshTheView();
}
/**
* set start color
*
* @param startColor start point color
*/
public void setStartColor(@ColorInt int startColor) {
this.mStartColor = startColor;
updateTheTrack();
mShader = new LinearGradient(mOval.left - 200, mOval.top - 200, mOval.right + 20, mOval.bottom + 20, mStartColor, mEndColor, Shader.TileMode.CLAMP);
refreshTheView();
}
/**
* set end color
*
* @param endColor end point color
*/
public void setEndColor(@ColorInt int endColor) {
this.mEndColor = endColor;
updateTheTrack();
mShader = new LinearGradient(mOval.left - 200, mOval.top - 200, mOval.right + 20, mOval.bottom + 20, mStartColor, mEndColor, Shader.TileMode.CLAMP);
refreshTheView();
}
/**
* set the width of progress stroke
*
* @param width stroke
*/
public void setTrackWidth(int width) {
mTrackWidth = DensityUtils.dp2px(getContext(), width);
trackPaint.setStrokeWidth(width);
updateTheTrack();
refreshTheView();
}
/**
* set the width of progress stroke
*
* @param width stroke
*/
public void setProgressWidth(int width) {
mProgressWidth = DensityUtils.dp2px(getContext(), width);
progressPaint.setStrokeWidth(width);
refreshTheView();
}
/**
* set text size for inner text
*
* @param size text size
*/
public void setProgressTextSize(int size) {
mProgressTextSize = DensityUtils.sp2px(getContext(), size);
refreshTheView();
}
/**
* set text color for progress text
*
* @param textColor
*/
public void setProgressTextColor(@ColorInt int textColor) {
this.mProgressTextColor = textColor;
}
/**
* set duration of progress moving
*
* @param duration
*/
public void setProgressDuration(int duration) {
this.mProgressDuration = duration;
}
/**
* set track for progress
*
* @param trackAble whether track or not
*/
public void setTrackEnabled(boolean trackAble) {
this.trackEnabled = trackAble;
refreshTheView();
}
/**
* set track color for progress background
*
* @param color bg color
*/
public void setTrackColor(@ColorInt int color) {
this.mTrackColor = color;
refreshTheView();
}
/**
* set content for progress inner space
*
* @param fillEnabled whether filled or not
*/
public void setFillEnabled(boolean fillEnabled) {
this.fillEnabled = fillEnabled;
refreshTheView();
}
/**
* set the broken circle for progress
*
* @param isBroken the circle broken or not
*/
public void setCircleBroken(boolean isBroken) {
this.circleBroken = isBroken;
refreshTheView();
}
/**
* set the scale zone type for progress view
*
* @param isGraduated have scale zone or not
*/
public void setGraduatedEnabled(final boolean isGraduated) {
this.isGraduated = isGraduated;
post(new Runnable() {
@Override
public void run() {
drawScaleZones(isGraduated);
}
});
}
/**
* set the scale zone width for it
*
* @param zoneWidth each zone 's width
*/
public void setScaleZoneWidth(float zoneWidth) {
this.mScaleZoneWidth = DensityUtils.dp2px(getContext(), zoneWidth);
}
/**
* set the scale zone length for it
*
* @param zoneLength each zone 's length
*/
public void setScaleZoneLength(float zoneLength) {
this.mScaleZoneLength = DensityUtils.dp2px(getContext(), zoneLength);
}
/**
* set each zone's distance
*
* @param zonePadding distance
*/
public void setScaleZonePadding(int zonePadding) {
this.mScaleZonePadding = DensityUtils.dp2px(getContext(), zonePadding);
}
/**
* set corner radius for each zone
*
* @param cornerRadius round rect zone's corner
*/
public void setScaleZoneCornerRadius(int cornerRadius) {
this.mScaleZoneCornerRadius = DensityUtils.dp2px(getContext(), cornerRadius);
}
/**
* set the visibility for progress inner text
*
* @param visibility text visible or not
*/
public void setProgressTextVisibility(boolean visibility) {
this.textVisibility = visibility;
}
/**
* start the progress's moving
*/
public void startProgressAnimation() {
progressAnimator = ObjectAnimator.ofFloat(this, "progress", mStartProgress, mEndProgress);
progressAnimator.setInterpolator(mInterpolator);
progressAnimator.setDuration(mProgressDuration);
progressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float progress = (float) animation.getAnimatedValue("progress");
if (mUpdateListener != null) {
mUpdateListener.onCircleProgressUpdate(CircleProgressView.this, progress);
}
}
});
progressAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
if (mUpdateListener != null) {
mUpdateListener.onCircleProgressStart(CircleProgressView.this);
}
}
@Override
public void onAnimationEnd(Animator animator) {
if (mUpdateListener != null) {
mUpdateListener.onCircleProgressFinished(CircleProgressView.this);
}
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
progressAnimator.start();
}
/**
* stop the progress moving
*/
public void stopProgressAnimation() {
if (progressAnimator != null) {
progressAnimator.cancel();
progressAnimator = null;
}
}
/**
* refresh the layout
*/
private void refreshTheView() {
invalidate();
requestLayout();
}
/**
* update the oval progress track
*/
private void updateTheTrack() {
if (mOval != null) {
mOval = null;
}
mOval = new RectF(getPaddingLeft() + mTrackWidth, getPaddingTop() + mTrackWidth, getWidth() - getPaddingRight() - mTrackWidth, getHeight() - getPaddingBottom() - mTrackWidth);
}
/**
* init the circle progress drawing
*
* @param canvas mCanvas
* @param isFilled filled or not
*/
private void initProgressDrawing(Canvas canvas, boolean isFilled) {
if (isFilled) {
progressPaint.setStyle(Paint.Style.FILL);
} else {
progressPaint.setStyle(Paint.Style.STROKE);
}
if (circleBroken) {
canvas.drawArc(mOval, 135 + mStartProgress * 2.7f, (moveProgress - mStartProgress) * 2.7f, isFilled, progressPaint);
} else {
canvas.drawArc(mOval, 270 + mStartProgress * 3.6f, (moveProgress - mStartProgress) * 3.6f, isFilled, progressPaint);
}
}
/**
* 进度条更新监听
*/
public interface CircleProgressUpdateListener {
/**
* 进度条开始更新
*
* @param view
*/
void onCircleProgressStart(View view);
/**
* 进度条更新中
*
* @param view
* @param progress
*/
void onCircleProgressUpdate(View view, float progress);
/**
* 进度条更新结束
*
* @param view
*/
void onCircleProgressFinished(View view);
}
/**
* set the progress update listener for progress view
*
* @param listener update listener
*/
public void setProgressViewUpdateListener(CircleProgressUpdateListener listener) {
this.mUpdateListener = listener;
}
}
See More Examples